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_syntax as syntax;
7use cairo_lang_syntax::node::ast::*;
8use cairo_lang_syntax::node::db::SyntaxGroup;
9use cairo_lang_syntax::node::kind::SyntaxKind;
10use cairo_lang_syntax::node::{SyntaxNode, Token, TypedSyntaxNode};
11use cairo_lang_utils::{LookupIntern, extract_matches, require};
12use syntax::node::green::{GreenNode, GreenNodeDetails};
13use syntax::node::ids::GreenId;
14
15use crate::ParserDiagnostic;
16use crate::diagnostic::ParserDiagnosticKind;
17use crate::lexer::{Lexer, LexerTerminal};
18use crate::operators::{get_post_operator_precedence, get_unary_operator_precedence};
19use crate::recovery::is_of_kind;
20use crate::types::TokenStream;
21use crate::validation::{validate_literal_number, validate_short_string, validate_string};
22
23#[cfg(test)]
24#[path = "parser_test.rs"]
25mod test;
26
27pub struct Parser<'a> {
28 db: &'a dyn SyntaxGroup,
29 file_id: FileId,
30 lexer: Lexer<'a>,
31 next_terminal: LexerTerminal,
33 pending_trivia: Vec<TriviumGreen>,
35 offset: TextOffset,
37 current_width: TextWidth,
40 last_trivia_length: TextWidth,
42 diagnostics: &'a mut DiagnosticsBuilder<ParserDiagnostic>,
43 pending_skipped_token_diagnostics: Vec<PendingParserDiagnostic>,
45}
46
47#[derive(PartialEq)]
49pub enum TryParseFailure {
50 SkipToken,
53 DoNothing,
58}
59pub type TryParseResult<GreenElement> = Result<GreenElement, TryParseFailure>;
61
62const MAX_PRECEDENCE: usize = 1000;
91const MODULE_ITEM_DESCRIPTION: &str = "Const/Enum/ExternFunction/ExternType/Function/Impl/\
92 InlineMacro/Module/Struct/Trait/TypeAlias/Use";
93const TRAIT_ITEM_DESCRIPTION: &str = "Const/Function/Impl/Type";
94const IMPL_ITEM_DESCRIPTION: &str = "Const/Function/Impl/Type";
95
96macro_rules! or_an_attribute {
98 ($string:expr) => {
99 format!("{} or an attribute", $string)
100 };
101}
102
103impl<'a> Parser<'a> {
104 fn new(
106 db: &'a dyn SyntaxGroup,
107 file_id: FileId,
108 text: &'a str,
109 diagnostics: &'a mut DiagnosticsBuilder<ParserDiagnostic>,
110 ) -> Self {
111 let mut lexer = Lexer::from_text(db, text);
112 let next_terminal = lexer.next().unwrap();
113 Parser {
114 db,
115 file_id,
116 lexer,
117 next_terminal,
118 pending_trivia: Vec::new(),
119 offset: Default::default(),
120 current_width: Default::default(),
121 last_trivia_length: Default::default(),
122 diagnostics,
123 pending_skipped_token_diagnostics: Vec::new(),
124 }
125 }
126
127 fn add_diagnostic(&mut self, kind: ParserDiagnosticKind, span: TextSpan) {
129 self.diagnostics.add(ParserDiagnostic { file_id: self.file_id, kind, span });
130 }
131
132 pub fn parse_file(
134 db: &'a dyn SyntaxGroup,
135 diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
136 file_id: FileId,
137 text: &'a str,
138 ) -> SyntaxFile {
139 let parser = Parser::new(db, file_id, text, diagnostics);
140 let green = parser.parse_syntax_file();
141 SyntaxFile::from_syntax_node(db, SyntaxNode::new_root(db, file_id, green.0))
142 }
143
144 pub fn parse_file_expr(
146 db: &'a dyn SyntaxGroup,
147 diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
148 file_id: FileId,
149 text: &'a str,
150 ) -> Expr {
151 let mut parser = Parser::new(db, file_id, text, diagnostics);
152 let green = parser.parse_expr();
153 if let Err(SkippedError(span)) = parser.skip_until(is_of_kind!()) {
154 parser.add_diagnostic(
155 ParserDiagnosticKind::SkippedElement { element_name: "end of expr".into() },
156 span,
157 );
158 }
159 Expr::from_syntax_node(db, SyntaxNode::new_root(db, file_id, green.0))
160 }
161
162 pub fn parse_token_stream(
164 db: &'a dyn SyntaxGroup,
165 diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
166 file_id: FileId,
167 token_stream: &'a dyn TokenStream,
168 ) -> SyntaxFile {
169 let parser = Parser::new(db, file_id, token_stream.as_str(), diagnostics);
170 let green = parser.parse_syntax_file();
171 SyntaxFile::from_syntax_node(
172 db,
173 SyntaxNode::new_root_with_offset(db, file_id, green.0, token_stream.get_start_offset()),
174 )
175 }
176
177 pub fn parse_token_stream_expr(
179 db: &'a dyn SyntaxGroup,
180 diagnostics: &mut DiagnosticsBuilder<ParserDiagnostic>,
181 file_id: FileId,
182 token_stream: &'a dyn TokenStream,
183 ) -> Expr {
184 let mut parser = Parser::new(db, file_id, token_stream.as_str(), diagnostics);
185 let green = parser.parse_expr();
186 if let Err(SkippedError(span)) = parser.skip_until(is_of_kind!()) {
187 parser.diagnostics.add(ParserDiagnostic {
188 file_id: parser.file_id,
189 kind: ParserDiagnosticKind::SkippedElement { element_name: "end of expr".into() },
190 span,
191 });
192 }
193 Expr::from_syntax_node(
194 db,
195 SyntaxNode::new_root_with_offset(db, file_id, green.0, token_stream.get_start_offset()),
196 )
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 => Ok(self.expect_item_const(attributes, visibility).into()),
266 SyntaxKind::TerminalModule => {
267 Ok(self.expect_item_module(attributes, visibility).into())
268 }
269 SyntaxKind::TerminalStruct => {
270 Ok(self.expect_item_struct(attributes, visibility).into())
271 }
272 SyntaxKind::TerminalEnum => Ok(self.expect_item_enum(attributes, visibility).into()),
273 SyntaxKind::TerminalType => {
274 Ok(self.expect_item_type_alias(attributes, visibility).into())
275 }
276 SyntaxKind::TerminalExtern => Ok(self.expect_item_extern(attributes, visibility)),
277 SyntaxKind::TerminalFunction => {
278 Ok(self.expect_item_function_with_body(attributes, visibility).into())
279 }
280 SyntaxKind::TerminalUse => Ok(self.expect_item_use(attributes, visibility).into()),
281 SyntaxKind::TerminalTrait => Ok(self.expect_item_trait(attributes, visibility).into()),
282 SyntaxKind::TerminalImpl => Ok(self.expect_module_item_impl(attributes, visibility)),
283 SyntaxKind::TerminalIdentifier => {
284 let ident = self.take_raw();
291 match self.peek().kind {
292 SyntaxKind::TerminalNot => {
293 let macro_name = self.add_trivia_to_terminal::<TerminalIdentifier>(ident);
295 Ok(self.expect_item_inline_macro(attributes, macro_name).into())
296 }
297 SyntaxKind::TerminalLParen
298 | SyntaxKind::TerminalLBrace
299 | SyntaxKind::TerminalLBrack => {
300 self.add_diagnostic(
302 ParserDiagnosticKind::ItemInlineMacroWithoutBang {
303 identifier: ident.clone().text,
304 bracket_type: self.peek().kind,
305 },
306 TextSpan {
307 start: self.offset,
308 end: self.offset.add_width(self.current_width),
309 },
310 );
311 let macro_name = self.add_trivia_to_terminal::<TerminalIdentifier>(ident);
312 Ok(self
313 .parse_item_inline_macro_given_bang(
314 attributes,
315 macro_name,
316 TerminalNot::missing(self.db),
317 )
318 .into())
319 }
320 _ => {
321 if has_attrs {
322 self.skip_taken_node_with_offset(
323 attributes,
324 ParserDiagnosticKind::SkippedElement {
325 element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION).into(),
326 },
327 post_attributes_offset,
328 );
329 }
330 if let Some(visibility_pub) = visibility_pub {
331 self.skip_taken_node_with_offset(
332 visibility_pub,
333 ParserDiagnosticKind::SkippedElement {
334 element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION).into(),
335 },
336 post_visibility_offset,
337 );
338 }
339 self.append_skipped_token_to_pending_trivia(
341 ident,
342 ParserDiagnosticKind::SkippedElement {
343 element_name: or_an_attribute!(MODULE_ITEM_DESCRIPTION).into(),
344 },
345 );
346 Err(TryParseFailure::DoNothing)
348 }
349 }
350 }
351 _ => {
352 let mut result = Err(TryParseFailure::SkipToken);
353 if has_attrs {
354 self.skip_taken_node_with_offset(
355 attributes,
356 ParserDiagnosticKind::AttributesWithoutItem,
357 post_attributes_offset,
358 );
359 result = Ok(ModuleItem::missing(self.db));
360 }
361 if let Some(visibility_pub) = visibility_pub {
362 self.skip_taken_node_with_offset(
363 visibility_pub,
364 ParserDiagnosticKind::VisibilityWithoutItem,
365 post_visibility_offset,
366 );
367 result = Ok(ModuleItem::missing(self.db));
368 }
369 result
370 }
371 }
372 }
373
374 fn expect_item_module(
377 &mut self,
378 attributes: AttributeListGreen,
379 visibility: VisibilityGreen,
380 ) -> ItemModuleGreen {
381 let module_kw = self.take::<TerminalModule>();
382 let name = self.parse_identifier();
383
384 let body = match self.peek().kind {
385 SyntaxKind::TerminalLBrace => {
386 let lbrace = self.take::<TerminalLBrace>();
387 let mut module_items = vec![];
388 if let Some(doc_item) = self.take_doc() {
389 module_items.push(doc_item.into());
390 }
391 module_items.extend(self.parse_attributed_list(
392 Self::try_parse_module_item,
393 is_of_kind!(rbrace),
394 MODULE_ITEM_DESCRIPTION,
395 ));
396 let items = ModuleItemList::new_green(self.db, module_items);
397 let rbrace = self.parse_token::<TerminalRBrace>();
398 ModuleBody::new_green(self.db, lbrace, items, rbrace).into()
399 }
400 _ => self.parse_token::<TerminalSemicolon>().into(),
402 };
403
404 ItemModule::new_green(self.db, attributes, visibility, module_kw, name, body)
405 }
406
407 fn expect_item_struct(
410 &mut self,
411 attributes: AttributeListGreen,
412 visibility: VisibilityGreen,
413 ) -> ItemStructGreen {
414 let struct_kw = self.take::<TerminalStruct>();
415 let name = self.parse_identifier();
416 let generic_params = self.parse_optional_generic_params();
417 let lbrace = self.parse_token::<TerminalLBrace>();
418 let members = self.parse_member_list();
419 let rbrace = self.parse_token::<TerminalRBrace>();
420 ItemStruct::new_green(
421 self.db,
422 attributes,
423 visibility,
424 struct_kw,
425 name,
426 generic_params,
427 lbrace,
428 members,
429 rbrace,
430 )
431 }
432
433 fn expect_item_enum(
436 &mut self,
437 attributes: AttributeListGreen,
438 visibility: VisibilityGreen,
439 ) -> ItemEnumGreen {
440 let enum_kw = self.take::<TerminalEnum>();
441 let name = self.parse_identifier();
442 let generic_params = self.parse_optional_generic_params();
443 let lbrace = self.parse_token::<TerminalLBrace>();
444 let variants = self.parse_variant_list();
445 let rbrace = self.parse_token::<TerminalRBrace>();
446 ItemEnum::new_green(
447 self.db,
448 attributes,
449 visibility,
450 enum_kw,
451 name,
452 generic_params,
453 lbrace,
454 variants,
455 rbrace,
456 )
457 }
458
459 fn expect_item_type_alias(
462 &mut self,
463 attributes: AttributeListGreen,
464 visibility: VisibilityGreen,
465 ) -> ItemTypeAliasGreen {
466 let type_kw = self.take::<TerminalType>();
467 let name = self.parse_identifier();
468 let generic_params = self.parse_optional_generic_params();
469 let eq = self.parse_token::<TerminalEq>();
470 let ty = self.parse_type_expr();
471 let semicolon = self.parse_token::<TerminalSemicolon>();
472 ItemTypeAlias::new_green(
473 self.db,
474 attributes,
475 visibility,
476 type_kw,
477 name,
478 generic_params,
479 eq,
480 ty,
481 semicolon,
482 )
483 }
484
485 fn expect_function_signature(&mut self) -> FunctionSignatureGreen {
487 let lparen = self.parse_token::<TerminalLParen>();
488 let params = self.parse_param_list();
489 let rparen = self.parse_token::<TerminalRParen>();
490 let return_type_clause = self.parse_option_return_type_clause();
491 let implicits_clause = self.parse_option_implicits_clause();
492 let optional_no_panic = if self.peek().kind == SyntaxKind::TerminalNoPanic {
493 self.take::<TerminalNoPanic>().into()
494 } else {
495 OptionTerminalNoPanicEmpty::new_green(self.db).into()
496 };
497
498 FunctionSignature::new_green(
499 self.db,
500 lparen,
501 params,
502 rparen,
503 return_type_clause,
504 implicits_clause,
505 optional_no_panic,
506 )
507 }
508
509 fn expect_item_const(
512 &mut self,
513 attributes: AttributeListGreen,
514 visibility: VisibilityGreen,
515 ) -> ItemConstantGreen {
516 let const_kw = self.take::<TerminalConst>();
517 let name = self.parse_identifier();
518 let type_clause = self.parse_type_clause(ErrorRecovery {
519 should_stop: is_of_kind!(eq, semicolon, module_item_kw),
520 });
521 let eq = self.parse_token::<TerminalEq>();
522 let expr = self.parse_expr();
523 let semicolon = self.parse_token::<TerminalSemicolon>();
524
525 ItemConstant::new_green(
526 self.db,
527 attributes,
528 visibility,
529 const_kw,
530 name,
531 type_clause,
532 eq,
533 expr,
534 semicolon,
535 )
536 }
537
538 fn expect_item_extern<T: From<ItemExternFunctionGreen> + From<ItemExternTypeGreen>>(
541 &mut self,
542 attributes: AttributeListGreen,
543 visibility: VisibilityGreen,
544 ) -> T {
545 match self.expect_item_extern_inner(attributes, visibility) {
546 ExternItem::Function(x) => x.into(),
547 ExternItem::Type(x) => x.into(),
548 }
549 }
550
551 fn expect_item_extern_inner(
554 &mut self,
555 attributes: AttributeListGreen,
556 visibility: VisibilityGreen,
557 ) -> ExternItem {
558 let extern_kw = self.take::<TerminalExtern>();
559 match self.peek().kind {
560 SyntaxKind::TerminalFunction => {
561 let declaration = self.expect_function_declaration();
562 let semicolon = self.parse_token::<TerminalSemicolon>();
563 ExternItem::Function(ItemExternFunction::new_green(
564 self.db,
565 attributes,
566 visibility,
567 extern_kw,
568 declaration,
569 semicolon,
570 ))
571 }
572 _ => {
573 let type_kw = self.parse_token::<TerminalType>();
575
576 let name = self.parse_identifier();
577 let generic_params = self.parse_optional_generic_params();
578 let semicolon = self.parse_token::<TerminalSemicolon>();
579 ExternItem::Type(ItemExternType::new_green(
581 self.db,
582 attributes,
583 visibility,
584 extern_kw,
585 type_kw,
586 name,
587 generic_params,
588 semicolon,
589 ))
590 }
591 }
592 }
593
594 fn expect_item_use(
597 &mut self,
598 attributes: AttributeListGreen,
599 visibility: VisibilityGreen,
600 ) -> ItemUseGreen {
601 let use_kw = self.take::<TerminalUse>();
602 let use_path = self.parse_use_path();
603 let semicolon = self.parse_token::<TerminalSemicolon>();
604 ItemUse::new_green(self.db, attributes, visibility, use_kw, use_path, semicolon)
605 }
606
607 fn try_parse_use_path(&mut self) -> TryParseResult<UsePathGreen> {
609 if !matches!(
610 self.peek().kind,
611 SyntaxKind::TerminalLBrace | SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalMul
612 ) {
613 return Err(TryParseFailure::SkipToken);
614 }
615 Ok(self.parse_use_path())
616 }
617
618 fn parse_use_path(&mut self) -> UsePathGreen {
620 match self.peek().kind {
621 SyntaxKind::TerminalLBrace => {
622 let lbrace = self.parse_token::<TerminalLBrace>();
623 let items = UsePathList::new_green(self.db,
624 self.parse_separated_list::<
625 UsePath, TerminalComma, UsePathListElementOrSeparatorGreen
626 >(
627 Self::try_parse_use_path,
628 is_of_kind!(rbrace, module_item_kw),
629 "path segment",
630 ));
631 let rbrace = self.parse_token::<TerminalRBrace>();
632 UsePathMulti::new_green(self.db, lbrace, items, rbrace).into()
633 }
634 SyntaxKind::TerminalMul => {
635 let star = self.parse_token::<TerminalMul>();
636 UsePathStar::new_green(self.db, star).into()
637 }
638 _ => {
639 if let Ok(ident) = self.try_parse_identifier() {
640 let ident = PathSegmentSimple::new_green(self.db, ident).into();
641 match self.peek().kind {
642 SyntaxKind::TerminalColonColon => {
643 let colon_colon = self.parse_token::<TerminalColonColon>();
644 let use_path = self.parse_use_path();
645 UsePathSingle::new_green(self.db, ident, colon_colon, use_path).into()
646 }
647 SyntaxKind::TerminalAs => {
648 let as_kw = self.take::<TerminalAs>();
649 let alias = self.parse_identifier();
650 let alias_clause = AliasClause::new_green(self.db, as_kw, alias).into();
651 UsePathLeaf::new_green(self.db, ident, alias_clause).into()
652 }
653 _ => {
654 let alias_clause = OptionAliasClauseEmpty::new_green(self.db).into();
655 UsePathLeaf::new_green(self.db, ident, alias_clause).into()
656 }
657 }
658 } else {
659 let missing = self.create_and_report_missing::<TerminalIdentifier>(
660 ParserDiagnosticKind::MissingPathSegment,
661 );
662 let ident = PathSegmentSimple::new_green(self.db, missing).into();
663 UsePathLeaf::new_green(
664 self.db,
665 ident,
666 OptionAliasClauseEmpty::new_green(self.db).into(),
667 )
668 .into()
669 }
670 }
671 }
672 }
673
674 fn try_parse_identifier(&mut self) -> TryParseResult<TerminalIdentifierGreen> {
679 if self.peek().kind.is_keyword_terminal() {
680 Ok(self.skip_token_and_return_missing::<TerminalIdentifier>(
682 ParserDiagnosticKind::ReservedIdentifier { identifier: self.peek().text.clone() },
683 ))
684 } else if self.peek().kind == SyntaxKind::TerminalUnderscore {
685 Ok(self.skip_token_and_return_missing::<TerminalIdentifier>(
686 ParserDiagnosticKind::UnderscoreNotAllowedAsIdentifier,
687 ))
688 } else {
689 self.try_parse_token::<TerminalIdentifier>()
690 }
691 }
692 fn is_peek_identifier_like(&self) -> bool {
698 let kind = self.peek().kind;
699 kind.is_keyword_terminal()
700 || matches!(kind, SyntaxKind::TerminalUnderscore | SyntaxKind::TerminalIdentifier)
701 }
702
703 fn parse_identifier(&mut self) -> TerminalIdentifierGreen {
705 match self.try_parse_identifier() {
706 Ok(identifier) => identifier,
707 Err(_) => self.create_and_report_missing_terminal::<TerminalIdentifier>(),
708 }
709 }
710
711 fn parse_visibility(&mut self) -> VisibilityGreen {
713 match self.try_parse_visibility_pub() {
714 Some(visibility) => visibility.into(),
715 None => VisibilityDefault::new_green(self.db).into(),
716 }
717 }
718
719 fn try_parse_visibility_pub(&mut self) -> Option<VisibilityPubGreen> {
721 require(self.peek().kind == SyntaxKind::TerminalPub)?;
722 let pub_kw = self.take::<TerminalPub>();
723 let argument_clause = if self.peek().kind != SyntaxKind::TerminalLParen {
724 OptionVisibilityPubArgumentClauseEmpty::new_green(self.db).into()
725 } else {
726 let lparen = self.parse_token::<TerminalLParen>();
727 let argument = self.parse_token::<TerminalIdentifier>();
728 let rparen = self.parse_token::<TerminalRParen>();
729 VisibilityPubArgumentClause::new_green(self.db, lparen, argument, rparen).into()
730 };
731 Some(VisibilityPub::new_green(self.db, pub_kw, argument_clause))
732 }
733
734 fn try_parse_attribute_list(
739 &mut self,
740 expected_elements_str: &str,
741 ) -> TryParseResult<AttributeListGreen> {
742 if self.peek().kind == SyntaxKind::TerminalHash {
743 Ok(self.parse_attribute_list(expected_elements_str))
744 } else {
745 Err(TryParseFailure::SkipToken)
746 }
747 }
748
749 fn parse_attribute_list(&mut self, expected_elements_str: &str) -> AttributeListGreen {
753 AttributeList::new_green(
754 self.db,
755 self.parse_list(
756 Self::try_parse_attribute,
757 |x| x != SyntaxKind::TerminalHash,
758 &or_an_attribute!(expected_elements_str),
759 ),
760 )
761 }
762
763 fn try_parse_attribute(&mut self) -> TryParseResult<AttributeGreen> {
766 match self.peek().kind {
767 SyntaxKind::TerminalHash => {
768 let hash = self.take::<TerminalHash>();
769 let lbrack = self.parse_token::<TerminalLBrack>();
770 let attr = self.parse_path();
771 let arguments = self.try_parse_parenthesized_argument_list();
772 let rbrack = self.parse_token::<TerminalRBrack>();
773
774 Ok(Attribute::new_green(self.db, hash, lbrack, attr, arguments, rbrack))
775 }
776 _ => Err(TryParseFailure::SkipToken),
777 }
778 }
779
780 fn expect_function_declaration(&mut self) -> FunctionDeclarationGreen {
783 let function_kw = self.take::<TerminalFunction>();
784 let name = self.parse_identifier();
785 let generic_params = self.parse_optional_generic_params();
786 let signature = self.expect_function_signature();
787
788 FunctionDeclaration::new_green(self.db, function_kw, name, generic_params, signature)
789 }
790
791 fn expect_item_function_with_body(
794 &mut self,
795 attributes: AttributeListGreen,
796 visibility: VisibilityGreen,
797 ) -> FunctionWithBodyGreen {
798 let declaration = self.expect_function_declaration();
799 let function_body = self.parse_block();
800 FunctionWithBody::new_green(self.db, attributes, visibility, declaration, function_body)
801 }
802
803 fn expect_item_trait(
805 &mut self,
806 attributes: AttributeListGreen,
807 visibility: VisibilityGreen,
808 ) -> ItemTraitGreen {
809 let trait_kw = self.take::<TerminalTrait>();
810 let name = self.parse_identifier();
811 let generic_params = self.parse_optional_generic_params();
812 let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
813 let lbrace = self.take::<TerminalLBrace>();
814 let items = TraitItemList::new_green(
815 self.db,
816 self.parse_attributed_list(
817 Self::try_parse_trait_item,
818 is_of_kind!(rbrace, module_item_kw),
819 TRAIT_ITEM_DESCRIPTION,
820 ),
821 );
822 let rbrace = self.parse_token::<TerminalRBrace>();
823 TraitBody::new_green(self.db, lbrace, items, rbrace).into()
824 } else {
825 self.parse_token::<TerminalSemicolon>().into()
826 };
827
828 ItemTrait::new_green(self.db, attributes, visibility, trait_kw, name, generic_params, body)
829 }
830
831 pub fn try_parse_trait_item(&mut self) -> TryParseResult<TraitItemGreen> {
834 let maybe_attributes = self.try_parse_attribute_list(TRAIT_ITEM_DESCRIPTION);
835
836 let (has_attrs, attributes) = match maybe_attributes {
837 Ok(attributes) => (true, attributes),
838 Err(_) => (false, AttributeList::new_green(self.db, vec![])),
839 };
840
841 match self.peek().kind {
842 SyntaxKind::TerminalFunction => Ok(self.expect_trait_item_function(attributes).into()),
843 SyntaxKind::TerminalType => Ok(self.expect_trait_item_type(attributes).into()),
844 SyntaxKind::TerminalConst => Ok(self.expect_trait_item_const(attributes).into()),
845 SyntaxKind::TerminalImpl => Ok(self.expect_trait_item_impl(attributes).into()),
846 _ => {
847 if has_attrs {
848 Ok(self.skip_taken_node_and_return_missing::<TraitItem>(
849 attributes,
850 ParserDiagnosticKind::AttributesWithoutTraitItem,
851 ))
852 } else {
853 Err(TryParseFailure::SkipToken)
854 }
855 }
856 }
857 }
858
859 fn expect_trait_item_function(
862 &mut self,
863 attributes: AttributeListGreen,
864 ) -> TraitItemFunctionGreen {
865 let declaration = self.expect_function_declaration();
866 let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
867 self.parse_block().into()
868 } else {
869 self.parse_token::<TerminalSemicolon>().into()
870 };
871 TraitItemFunction::new_green(self.db, attributes, declaration, body)
872 }
873
874 fn expect_trait_item_type(&mut self, attributes: AttributeListGreen) -> TraitItemTypeGreen {
877 let type_kw = self.take::<TerminalType>();
878 let name = self.parse_identifier();
879 let generic_params = self.parse_optional_generic_params();
880 let semicolon = self.parse_token::<TerminalSemicolon>();
881 TraitItemType::new_green(self.db, attributes, type_kw, name, generic_params, semicolon)
882 }
883
884 fn expect_trait_item_const(
887 &mut self,
888 attributes: AttributeListGreen,
889 ) -> TraitItemConstantGreen {
890 let const_kw = self.take::<TerminalConst>();
891 let name = self.parse_identifier();
892 let type_clause = self.parse_type_clause(ErrorRecovery {
893 should_stop: is_of_kind!(eq, semicolon, module_item_kw),
894 });
895 let semicolon = self.parse_token::<TerminalSemicolon>();
896
897 TraitItemConstant::new_green(self.db, attributes, const_kw, name, type_clause, semicolon)
898 }
899
900 fn expect_trait_item_impl(&mut self, attributes: AttributeListGreen) -> TraitItemImplGreen {
903 let impl_kw = self.take::<TerminalImpl>();
904 let name = self.parse_identifier();
905 let colon = self.parse_token::<TerminalColon>();
906 let trait_path = self.parse_type_path();
907 let semicolon = self.parse_token::<TerminalSemicolon>();
908 TraitItemImpl::new_green(self.db, attributes, impl_kw, name, colon, trait_path, semicolon)
909 }
910
911 fn expect_module_item_impl(
913 &mut self,
914 attributes: AttributeListGreen,
915 visibility: VisibilityGreen,
916 ) -> ModuleItemGreen {
917 match self.expect_item_impl_inner(attributes, visibility, false) {
918 ImplItemOrAlias::Item(green) => green.into(),
919 ImplItemOrAlias::Alias(green) => green.into(),
920 }
921 }
922
923 fn expect_impl_item_impl(
926 &mut self,
927 attributes: AttributeListGreen,
928 visibility: VisibilityGreen,
929 ) -> ItemImplAliasGreen {
930 extract_matches!(
931 self.expect_item_impl_inner(attributes, visibility, true),
932 ImplItemOrAlias::Alias
933 )
934 }
935
936 fn expect_item_impl_inner(
941 &mut self,
942 attributes: AttributeListGreen,
943 visibility: VisibilityGreen,
944 only_allow_alias: bool,
945 ) -> ImplItemOrAlias {
946 let impl_kw = self.take::<TerminalImpl>();
947 let name = self.parse_identifier();
948 let generic_params = self.parse_optional_generic_params();
949
950 if self.peek().kind == SyntaxKind::TerminalEq || only_allow_alias {
951 let eq = self.parse_token::<TerminalEq>();
952 let impl_path = self.parse_type_path();
953 let semicolon = self.parse_token::<TerminalSemicolon>();
954
955 return ImplItemOrAlias::Alias(ItemImplAlias::new_green(
956 self.db,
957 attributes,
958 visibility,
959 impl_kw,
960 name,
961 generic_params,
962 eq,
963 impl_path,
964 semicolon,
965 ));
966 }
967
968 let of_kw = self.parse_token::<TerminalOf>();
969 let trait_path = self.parse_type_path();
970 let body = if self.peek().kind == SyntaxKind::TerminalLBrace {
971 let lbrace = self.take::<TerminalLBrace>();
972 let items = ImplItemList::new_green(
973 self.db,
974 self.parse_attributed_list(
975 Self::try_parse_impl_item,
976 is_of_kind!(rbrace),
977 IMPL_ITEM_DESCRIPTION,
978 ),
979 );
980 let rbrace = self.parse_token::<TerminalRBrace>();
981 ImplBody::new_green(self.db, lbrace, items, rbrace).into()
982 } else {
983 self.parse_token::<TerminalSemicolon>().into()
984 };
985
986 ImplItemOrAlias::Item(ItemImpl::new_green(
987 self.db,
988 attributes,
989 visibility,
990 impl_kw,
991 name,
992 generic_params,
993 of_kw,
994 trait_path,
995 body,
996 ))
997 }
998
999 pub fn try_parse_impl_item(&mut self) -> TryParseResult<ImplItemGreen> {
1002 let maybe_attributes = self.try_parse_attribute_list(IMPL_ITEM_DESCRIPTION);
1003
1004 let (has_attrs, attributes) = match maybe_attributes {
1005 Ok(attributes) => (true, attributes),
1006 Err(_) => (false, AttributeList::new_green(self.db, vec![])),
1007 };
1008
1009 let visibility = VisibilityDefault::new_green(self.db).into();
1012
1013 match self.peek().kind {
1014 SyntaxKind::TerminalFunction => {
1015 Ok(self.expect_item_function_with_body(attributes, visibility).into())
1016 }
1017 SyntaxKind::TerminalType => {
1018 Ok(self.expect_item_type_alias(attributes, visibility).into())
1019 }
1020 SyntaxKind::TerminalConst => Ok(self.expect_item_const(attributes, visibility).into()),
1021 SyntaxKind::TerminalImpl => {
1022 Ok(self.expect_impl_item_impl(attributes, visibility).into())
1023 }
1024 SyntaxKind::TerminalModule => {
1026 Ok(self.expect_item_module(attributes, visibility).into())
1027 }
1028 SyntaxKind::TerminalStruct => {
1029 Ok(self.expect_item_struct(attributes, visibility).into())
1030 }
1031 SyntaxKind::TerminalEnum => Ok(self.expect_item_enum(attributes, visibility).into()),
1032 SyntaxKind::TerminalExtern => Ok(self.expect_item_extern(attributes, visibility)),
1033 SyntaxKind::TerminalUse => Ok(self.expect_item_use(attributes, visibility).into()),
1034 SyntaxKind::TerminalTrait => Ok(self.expect_item_trait(attributes, visibility).into()),
1035 _ => {
1036 if has_attrs {
1037 Ok(self.skip_taken_node_and_return_missing::<ImplItem>(
1038 attributes,
1039 ParserDiagnosticKind::AttributesWithoutImplItem,
1040 ))
1041 } else {
1042 Err(TryParseFailure::SkipToken)
1043 }
1044 }
1045 }
1046 }
1047
1048 fn expect_item_inline_macro(
1050 &mut self,
1051 attributes: AttributeListGreen,
1052 name: TerminalIdentifierGreen,
1053 ) -> ItemInlineMacroGreen {
1054 let bang = self.parse_token::<TerminalNot>();
1055 self.parse_item_inline_macro_given_bang(attributes, name, bang)
1056 }
1057
1058 fn parse_item_inline_macro_given_bang(
1060 &mut self,
1061 attributes: AttributeListGreen,
1062 name: TerminalIdentifierGreen,
1063 bang: TerminalNotGreen,
1064 ) -> ItemInlineMacroGreen {
1065 let arguments = self.parse_wrapped_arg_list();
1066 let semicolon = self.parse_token::<TerminalSemicolon>();
1067 ItemInlineMacro::new_green(self.db, attributes, name, bang, arguments, semicolon)
1068 }
1069
1070 fn try_parse_expr(&mut self) -> TryParseResult<ExprGreen> {
1075 self.try_parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Allow)
1076 }
1077 pub fn parse_expr(&mut self) -> ExprGreen {
1080 match self.try_parse_expr() {
1081 Ok(green) => green,
1082 Err(_) => {
1083 self.create_and_report_missing::<Expr>(ParserDiagnosticKind::MissingExpression)
1084 }
1085 }
1086 }
1087
1088 fn parse_binary_operator(&mut self) -> BinaryOperatorGreen {
1092 match self.peek().kind {
1095 SyntaxKind::TerminalDot => self.take::<TerminalDot>().into(),
1096 SyntaxKind::TerminalMul => self.take::<TerminalMul>().into(),
1097 SyntaxKind::TerminalMulEq => self.take::<TerminalMulEq>().into(),
1098 SyntaxKind::TerminalDiv => self.take::<TerminalDiv>().into(),
1099 SyntaxKind::TerminalDivEq => self.take::<TerminalDivEq>().into(),
1100 SyntaxKind::TerminalMod => self.take::<TerminalMod>().into(),
1101 SyntaxKind::TerminalModEq => self.take::<TerminalModEq>().into(),
1102 SyntaxKind::TerminalPlus => self.take::<TerminalPlus>().into(),
1103 SyntaxKind::TerminalPlusEq => self.take::<TerminalPlusEq>().into(),
1104 SyntaxKind::TerminalMinus => self.take::<TerminalMinus>().into(),
1105 SyntaxKind::TerminalMinusEq => self.take::<TerminalMinusEq>().into(),
1106 SyntaxKind::TerminalEq => self.take::<TerminalEq>().into(),
1107 SyntaxKind::TerminalEqEq => self.take::<TerminalEqEq>().into(),
1108 SyntaxKind::TerminalNeq => self.take::<TerminalNeq>().into(),
1109 SyntaxKind::TerminalLT => self.take::<TerminalLT>().into(),
1110 SyntaxKind::TerminalGT => self.take::<TerminalGT>().into(),
1111 SyntaxKind::TerminalLE => self.take::<TerminalLE>().into(),
1112 SyntaxKind::TerminalGE => self.take::<TerminalGE>().into(),
1113 SyntaxKind::TerminalAnd => self.take::<TerminalAnd>().into(),
1114 SyntaxKind::TerminalAndAnd => self.take::<TerminalAndAnd>().into(),
1115 SyntaxKind::TerminalOrOr => self.take::<TerminalOrOr>().into(),
1116 SyntaxKind::TerminalOr => self.take::<TerminalOr>().into(),
1117 SyntaxKind::TerminalXor => self.take::<TerminalXor>().into(),
1118 SyntaxKind::TerminalDotDot => self.take::<TerminalDotDot>().into(),
1119 _ => unreachable!(),
1120 }
1121 }
1122
1123 fn expect_unary_operator(&mut self) -> UnaryOperatorGreen {
1125 match self.peek().kind {
1126 SyntaxKind::TerminalAt => self.take::<TerminalAt>().into(),
1127 SyntaxKind::TerminalNot => self.take::<TerminalNot>().into(),
1128 SyntaxKind::TerminalBitNot => self.take::<TerminalBitNot>().into(),
1129 SyntaxKind::TerminalMinus => self.take::<TerminalMinus>().into(),
1130 SyntaxKind::TerminalMul => self.take::<TerminalMul>().into(),
1131 _ => unreachable!(),
1132 }
1133 }
1134
1135 fn is_comparison_operator(&self, kind: SyntaxKind) -> bool {
1147 matches!(
1148 kind,
1149 SyntaxKind::TerminalLT
1150 | SyntaxKind::TerminalGT
1151 | SyntaxKind::TerminalLE
1152 | SyntaxKind::TerminalGE
1153 | SyntaxKind::TerminalEqEq
1154 | SyntaxKind::TerminalNeq
1155 )
1156 }
1157
1158 fn try_parse_expr_limited(
1165 &mut self,
1166 parent_precedence: usize,
1167 lbrace_allowed: LbraceAllowed,
1168 ) -> TryParseResult<ExprGreen> {
1169 let mut expr = self.try_parse_atom_or_unary(lbrace_allowed)?;
1170 let mut child_op: Option<SyntaxKind> = None;
1171 while let Some(precedence) = get_post_operator_precedence(self.peek().kind) {
1172 if precedence >= parent_precedence {
1173 return Ok(expr);
1174 }
1175 expr = if self.peek().kind == SyntaxKind::TerminalQuestionMark {
1176 ExprErrorPropagate::new_green(self.db, expr, self.take::<TerminalQuestionMark>())
1177 .into()
1178 } else if self.peek().kind == SyntaxKind::TerminalLBrack {
1179 let lbrack = self.take::<TerminalLBrack>();
1180 let index_expr = self.parse_expr();
1181 let rbrack = self.parse_token::<TerminalRBrack>();
1182 ExprIndexed::new_green(self.db, expr, lbrack, index_expr, rbrack).into()
1183 } else {
1184 let current_op = self.peek().kind;
1185 if let Some(child_op_kind) = child_op {
1186 if self.is_comparison_operator(child_op_kind)
1187 && self.is_comparison_operator(current_op)
1188 {
1189 self.add_diagnostic(
1190 ParserDiagnosticKind::ConsecutiveMathOperators {
1191 first_op: child_op_kind,
1192 second_op: current_op,
1193 },
1194 TextSpan { start: self.offset, end: self.offset },
1195 );
1196 }
1197 }
1198 child_op = Some(current_op);
1199 let op = self.parse_binary_operator();
1200 let rhs = self.parse_expr_limited(precedence, lbrace_allowed);
1201 ExprBinary::new_green(self.db, expr, op, rhs).into()
1202 };
1203 }
1204 Ok(expr)
1205 }
1206
1207 fn try_parse_atom_or_unary(
1213 &mut self,
1214 lbrace_allowed: LbraceAllowed,
1215 ) -> TryParseResult<ExprGreen> {
1216 let Some(precedence) = get_unary_operator_precedence(self.peek().kind) else {
1217 return self.try_parse_atom(lbrace_allowed);
1218 };
1219 let op = self.expect_unary_operator();
1220 let expr = self.parse_expr_limited(precedence, lbrace_allowed);
1221 Ok(ExprUnary::new_green(self.db, op, expr).into())
1222 }
1223
1224 fn parse_expr_limited(
1229 &mut self,
1230 parent_precedence: usize,
1231 lbrace_allowed: LbraceAllowed,
1232 ) -> ExprGreen {
1233 match self.try_parse_expr_limited(parent_precedence, lbrace_allowed) {
1234 Ok(green) => green,
1235 Err(_) => {
1236 self.create_and_report_missing::<Expr>(ParserDiagnosticKind::MissingExpression)
1237 }
1238 }
1239 }
1240
1241 fn try_parse_atom(&mut self, lbrace_allowed: LbraceAllowed) -> TryParseResult<ExprGreen> {
1247 match self.peek().kind {
1249 SyntaxKind::TerminalIdentifier => {
1250 let path = self.parse_path();
1252 match self.peek().kind {
1253 SyntaxKind::TerminalLParen => Ok(self.expect_function_call(path).into()),
1254 SyntaxKind::TerminalLBrace if lbrace_allowed == LbraceAllowed::Allow => {
1255 Ok(self.expect_constructor_call(path).into())
1256 }
1257 SyntaxKind::TerminalNot => Ok(self.expect_macro_call(path).into()),
1258 _ => Ok(path.into()),
1259 }
1260 }
1261 SyntaxKind::TerminalFalse => Ok(self.take::<TerminalFalse>().into()),
1262 SyntaxKind::TerminalTrue => Ok(self.take::<TerminalTrue>().into()),
1263 SyntaxKind::TerminalLiteralNumber => Ok(self.take_terminal_literal_number().into()),
1264 SyntaxKind::TerminalShortString => Ok(self.take_terminal_short_string().into()),
1265 SyntaxKind::TerminalString => Ok(self.take_terminal_string().into()),
1266 SyntaxKind::TerminalLParen => {
1267 Ok(self.expect_parenthesized_expr())
1270 }
1271 SyntaxKind::TerminalLBrack => Ok(self.expect_fixed_size_array_expr().into()),
1272 SyntaxKind::TerminalLBrace if lbrace_allowed == LbraceAllowed::Allow => {
1273 Ok(self.parse_block().into())
1274 }
1275 SyntaxKind::TerminalMatch if lbrace_allowed == LbraceAllowed::Allow => {
1276 Ok(self.expect_match_expr().into())
1277 }
1278 SyntaxKind::TerminalIf if lbrace_allowed == LbraceAllowed::Allow => {
1279 Ok(self.expect_if_expr().into())
1280 }
1281 SyntaxKind::TerminalLoop if lbrace_allowed == LbraceAllowed::Allow => {
1282 Ok(self.expect_loop_expr().into())
1283 }
1284 SyntaxKind::TerminalWhile if lbrace_allowed == LbraceAllowed::Allow => {
1285 Ok(self.expect_while_expr().into())
1286 }
1287 SyntaxKind::TerminalFor if lbrace_allowed == LbraceAllowed::Allow => {
1288 Ok(self.expect_for_expr().into())
1289 }
1290 SyntaxKind::TerminalOr if lbrace_allowed == LbraceAllowed::Allow => {
1291 Ok(self.expect_closure_expr_nary().into())
1292 }
1293 SyntaxKind::TerminalOrOr if lbrace_allowed == LbraceAllowed::Allow => {
1294 Ok(self.expect_closure_expr_nullary().into())
1295 }
1296
1297 _ => {
1298 Err(TryParseFailure::SkipToken)
1300 }
1301 }
1302 }
1303
1304 fn try_parse_type_expr(&mut self) -> TryParseResult<ExprGreen> {
1307 match self.peek().kind {
1309 SyntaxKind::TerminalAt => {
1310 let op = self.take::<TerminalAt>().into();
1311 let expr = self.parse_type_expr();
1312 Ok(ExprUnary::new_green(self.db, op, expr).into())
1313 }
1314 SyntaxKind::TerminalIdentifier => Ok(self.parse_type_path().into()),
1315 SyntaxKind::TerminalLParen => Ok(self.expect_type_tuple_expr()),
1316 SyntaxKind::TerminalLBrack => Ok(self.expect_type_fixed_size_array_expr()),
1317 _ => {
1318 Err(TryParseFailure::SkipToken)
1320 }
1321 }
1322 }
1323
1324 fn parse_type_expr(&mut self) -> ExprGreen {
1327 match self.try_parse_type_expr() {
1328 Ok(expr) => expr,
1329 Err(_) => {
1330 self.create_and_report_missing::<Expr>(ParserDiagnosticKind::MissingTypeExpression)
1331 }
1332 }
1333 }
1334
1335 fn expect_struct_ctor_argument_list_braced(&mut self) -> StructArgListBracedGreen {
1338 let lbrace = self.take::<TerminalLBrace>();
1339 let arg_list = StructArgList::new_green(
1340 self.db,
1341 self.parse_separated_list::<StructArg, TerminalComma, StructArgListElementOrSeparatorGreen>(
1342 Self::try_parse_struct_ctor_argument,
1343 is_of_kind!(rparen, block, rbrace, module_item_kw),
1344 "struct constructor argument",
1345 ),
1346 );
1347 let rbrace = self.parse_token::<TerminalRBrace>();
1348
1349 StructArgListBraced::new_green(self.db, lbrace, arg_list, rbrace)
1350 }
1351
1352 fn expect_function_call(&mut self, path: ExprPathGreen) -> ExprFunctionCallGreen {
1355 let func_name = path;
1356 let parenthesized_args = self.expect_parenthesized_argument_list();
1357 ExprFunctionCall::new_green(self.db, func_name, parenthesized_args)
1358 }
1359
1360 fn expect_macro_call(&mut self, path: ExprPathGreen) -> ExprInlineMacroGreen {
1363 let bang = self.take::<TerminalNot>();
1364 let macro_name = path;
1365 let wrapped_expr_list = self.parse_wrapped_arg_list();
1366 ExprInlineMacro::new_green(self.db, macro_name, bang, wrapped_expr_list)
1367 }
1368
1369 fn parse_wrapped_arg_list(&mut self) -> WrappedArgListGreen {
1372 let current_token = self.peek().kind;
1373 match current_token {
1374 SyntaxKind::TerminalLParen => self
1375 .expect_wrapped_argument_list::<TerminalLParen, TerminalRParen, _, _>(
1376 ArgListParenthesized::new_green,
1377 )
1378 .into(),
1379 SyntaxKind::TerminalLBrack => self
1380 .expect_wrapped_argument_list::<TerminalLBrack, TerminalRBrack, _, _>(
1381 ArgListBracketed::new_green,
1382 )
1383 .into(),
1384 SyntaxKind::TerminalLBrace => self
1385 .expect_wrapped_argument_list::<TerminalLBrace, TerminalRBrace, _, _>(
1386 ArgListBraced::new_green,
1387 )
1388 .into(),
1389 _ => self.create_and_report_missing::<WrappedArgList>(
1390 ParserDiagnosticKind::MissingWrappedArgList,
1391 ),
1392 }
1393 }
1394
1395 fn expect_wrapped_argument_list<
1400 LTerminal: syntax::node::Terminal,
1401 RTerminal: syntax::node::Terminal,
1402 ListGreen,
1403 NewGreen: Fn(&dyn SyntaxGroup, LTerminal::Green, ArgListGreen, RTerminal::Green) -> ListGreen,
1404 >(
1405 &mut self,
1406 new_green: NewGreen,
1407 ) -> ListGreen {
1408 let l_term = self.take::<LTerminal>();
1409 let exprs: Vec<ArgListElementOrSeparatorGreen> = self
1410 .parse_separated_list::<Arg, TerminalComma, ArgListElementOrSeparatorGreen>(
1411 Self::try_parse_function_argument,
1412 is_of_kind!(rparen, rbrace, rbrack, block, module_item_kw),
1413 "argument",
1414 );
1415 let r_term: <RTerminal as TypedSyntaxNode>::Green = self.parse_token::<RTerminal>();
1416 new_green(self.db, l_term, ArgList::new_green(self.db, exprs), r_term)
1417 }
1418
1419 fn expect_parenthesized_argument_list(&mut self) -> ArgListParenthesizedGreen {
1422 self.expect_wrapped_argument_list::<TerminalLParen, TerminalRParen, _, _>(
1423 ArgListParenthesized::new_green,
1424 )
1425 }
1426
1427 fn try_parse_parenthesized_argument_list(&mut self) -> OptionArgListParenthesizedGreen {
1430 if self.peek().kind == SyntaxKind::TerminalLParen {
1431 self.expect_parenthesized_argument_list().into()
1432 } else {
1433 OptionArgListParenthesizedEmpty::new_green(self.db).into()
1434 }
1435 }
1436
1437 fn try_parse_function_argument(&mut self) -> TryParseResult<ArgGreen> {
1439 let modifiers_list = self.parse_modifier_list();
1440 let arg_clause = self.try_parse_argument_clause();
1441 match arg_clause {
1442 Ok(arg_clause) => {
1443 let modifiers = ModifierList::new_green(self.db, modifiers_list);
1444 Ok(Arg::new_green(self.db, modifiers, arg_clause))
1445 }
1446 Err(_) if !modifiers_list.is_empty() => {
1447 let modifiers = ModifierList::new_green(self.db, modifiers_list);
1448 let arg_clause = ArgClauseUnnamed::new_green(self.db, self.parse_expr()).into();
1449 Ok(Arg::new_green(self.db, modifiers, arg_clause))
1450 }
1451 Err(err) => Err(err),
1452 }
1453 }
1454
1455 fn try_parse_argument_clause(&mut self) -> TryParseResult<ArgClauseGreen> {
1463 if self.peek().kind == SyntaxKind::TerminalColon {
1464 let colon = self.take::<TerminalColon>();
1465 let name = self.parse_identifier();
1466 return Ok(ArgClauseFieldInitShorthand::new_green(
1467 self.db,
1468 colon,
1469 ExprFieldInitShorthand::new_green(self.db, name),
1470 )
1471 .into());
1472 }
1473
1474 let value = self.try_parse_expr()?;
1476
1477 if self.peek().kind == SyntaxKind::TerminalColon {
1480 if let Some(argname) = self.try_extract_identifier(value) {
1481 let colon = self.take::<TerminalColon>();
1482 let expr = self.parse_expr();
1483 return Ok(ArgClauseNamed::new_green(self.db, argname, colon, expr).into());
1484 }
1485 }
1486
1487 Ok(ArgClauseUnnamed::new_green(self.db, value).into())
1488 }
1489
1490 fn try_extract_identifier(&self, expr: ExprGreen) -> Option<TerminalIdentifierGreen> {
1493 let GreenNode {
1495 kind: SyntaxKind::ExprPath,
1496 details: GreenNodeDetails::Node { children: children0, .. },
1497 } = &*expr.0.lookup_intern(self.db)
1498 else {
1499 return None;
1500 };
1501
1502 let [path_segment] = children0[..] else {
1504 return None;
1505 };
1506
1507 let GreenNode {
1509 kind: SyntaxKind::PathSegmentSimple,
1510 details: GreenNodeDetails::Node { children: children1, .. },
1511 } = &*path_segment.lookup_intern(self.db)
1512 else {
1513 return None;
1514 };
1515
1516 let [ident] = children1[..] else {
1518 return None;
1519 };
1520
1521 let GreenNode { kind: SyntaxKind::TerminalIdentifier, .. } =
1523 ident.lookup_intern(self.db).as_ref()
1524 else {
1525 return None;
1526 };
1527
1528 Some(TerminalIdentifierGreen(ident))
1529 }
1530
1531 fn expect_constructor_call(&mut self, path: ExprPathGreen) -> ExprStructCtorCallGreen {
1534 let ctor_name = path;
1535 let args = self.expect_struct_ctor_argument_list_braced();
1536 ExprStructCtorCall::new_green(self.db, ctor_name, args)
1537 }
1538
1539 fn expect_parenthesized_expr(&mut self) -> ExprGreen {
1543 let lparen = self.take::<TerminalLParen>();
1544 let exprs: Vec<ExprListElementOrSeparatorGreen> = self
1545 .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
1546 Self::try_parse_expr,
1547 is_of_kind!(rparen, block, rbrace, module_item_kw),
1548 "expression",
1549 );
1550 let rparen = self.parse_token::<TerminalRParen>();
1551
1552 if let [ExprListElementOrSeparatorGreen::Element(expr)] = &exprs[..] {
1553 ExprParenthesized::new_green(self.db, lparen, *expr, rparen).into()
1555 } else {
1556 ExprListParenthesized::new_green(
1557 self.db,
1558 lparen,
1559 ExprList::new_green(self.db, exprs),
1560 rparen,
1561 )
1562 .into()
1563 }
1564 }
1565
1566 fn expect_type_tuple_expr(&mut self) -> ExprGreen {
1570 let lparen = self.take::<TerminalLParen>();
1571 let exprs: Vec<ExprListElementOrSeparatorGreen> = self
1572 .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
1573 Self::try_parse_type_expr,
1574 is_of_kind!(rparen, block, rbrace, module_item_kw),
1575 "type expression",
1576 );
1577 let rparen = self.parse_token::<TerminalRParen>();
1578 if let [ExprListElementOrSeparatorGreen::Element(_)] = &exprs[..] {
1579 self.add_diagnostic(
1580 ParserDiagnosticKind::MissingToken(SyntaxKind::TokenComma),
1581 TextSpan { start: self.offset, end: self.offset },
1582 );
1583 }
1584 ExprListParenthesized::new_green(
1585 self.db,
1586 lparen,
1587 ExprList::new_green(self.db, exprs),
1588 rparen,
1589 )
1590 .into()
1591 }
1592
1593 fn expect_type_fixed_size_array_expr(&mut self) -> ExprGreen {
1597 let lbrack = self.take::<TerminalLBrack>();
1598 let exprs: Vec<ExprListElementOrSeparatorGreen> = self
1599 .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
1600 Self::try_parse_type_expr,
1601 is_of_kind!(rbrack, semicolon),
1602 "type expression",
1603 );
1604 let semicolon = self.parse_token::<TerminalSemicolon>();
1605 let size_expr = self.parse_expr();
1606 let fixed_size_array_size =
1607 FixedSizeArraySize::new_green(self.db, semicolon, size_expr).into();
1608 let rbrack = self.parse_token::<TerminalRBrack>();
1609 ExprFixedSizeArray::new_green(
1610 self.db,
1611 lbrack,
1612 ExprList::new_green(self.db, exprs),
1613 fixed_size_array_size,
1614 rbrack,
1615 )
1616 .into()
1617 }
1618
1619 fn expect_struct_argument_tail(&mut self) -> StructArgTailGreen {
1622 let dotdot = self.take::<TerminalDotDot>(); let expr = self.parse_expr();
1625 StructArgTail::new_green(self.db, dotdot, expr)
1626 }
1627
1628 fn try_parse_struct_ctor_argument(&mut self) -> TryParseResult<StructArgGreen> {
1633 match self.peek().kind {
1634 SyntaxKind::TerminalDotDot => Ok(self.expect_struct_argument_tail().into()),
1635 _ => self.try_parse_argument_single().map(|arg| arg.into()),
1636 }
1637 }
1638
1639 fn parse_option_struct_arg_expression(&mut self) -> OptionStructArgExprGreen {
1642 if self.peek().kind == SyntaxKind::TerminalColon {
1643 let colon = self.take::<TerminalColon>();
1644 let value = self.parse_expr();
1645 StructArgExpr::new_green(self.db, colon, value).into()
1646 } else {
1647 OptionStructArgExprEmpty::new_green(self.db).into()
1648 }
1649 }
1650
1651 fn parse_option_expression_clause(&mut self) -> OptionExprClauseGreen {
1654 if self.peek().kind == SyntaxKind::TerminalSemicolon {
1655 OptionExprClauseEmpty::new_green(self.db).into()
1656 } else {
1657 let value = self.parse_expr();
1658 ExprClause::new_green(self.db, value).into()
1659 }
1660 }
1661
1662 fn try_parse_argument_single(&mut self) -> TryParseResult<StructArgSingleGreen> {
1664 let identifier = self.try_parse_identifier()?;
1665 let struct_arg_expr = self.parse_option_struct_arg_expression(); Ok(StructArgSingle::new_green(self.db, identifier, struct_arg_expr))
1667 }
1668
1669 fn parse_block(&mut self) -> ExprBlockGreen {
1671 let skipped_tokens = self.skip_until(is_of_kind!(rbrace, lbrace, module_item_kw, block));
1672
1673 if let Err(SkippedError(span)) = skipped_tokens {
1674 self.add_diagnostic(
1675 ParserDiagnosticKind::SkippedElement { element_name: "'{'".into() },
1676 span,
1677 );
1678 }
1679
1680 let is_rbrace_or_top_level = is_of_kind!(rbrace, module_item_kw);
1681 if is_rbrace_or_top_level(self.peek().kind) {
1682 return ExprBlock::new_green(
1683 self.db,
1684 self.create_and_report_missing_terminal::<TerminalLBrace>(),
1685 StatementList::new_green(self.db, vec![]),
1686 TerminalRBrace::missing(self.db),
1687 );
1688 }
1689 let lbrace = self.parse_token_ex::<TerminalLBrace>(skipped_tokens.is_ok());
1691 let statements = StatementList::new_green(
1692 self.db,
1693 self.parse_list(
1694 Self::try_parse_statement,
1695 is_of_kind!(rbrace, module_item_kw),
1696 "statement",
1697 ),
1698 );
1699 let rbrace = self.parse_token::<TerminalRBrace>();
1700 ExprBlock::new_green(self.db, lbrace, statements, rbrace)
1701 }
1702
1703 fn expect_match_expr(&mut self) -> ExprMatchGreen {
1706 let match_kw = self.take::<TerminalMatch>();
1707 let expr = self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid);
1708 let lbrace = self.parse_token::<TerminalLBrace>();
1709 let arms = MatchArms::new_green(
1710 self.db,
1711 self.parse_separated_list::<MatchArm, TerminalComma, MatchArmsElementOrSeparatorGreen>(
1712 Self::try_parse_match_arm,
1713 is_of_kind!(block, rbrace, module_item_kw),
1714 "match arm",
1715 ),
1716 );
1717 let rbrace = self.parse_token::<TerminalRBrace>();
1718 ExprMatch::new_green(self.db, match_kw, expr, lbrace, arms, rbrace)
1719 }
1720
1721 fn expect_if_expr(&mut self) -> ExprIfGreen {
1723 let if_kw = self.take::<TerminalIf>();
1724
1725 let condition = self.parse_condition_expr();
1726 let if_block = self.parse_block();
1727 let else_clause = if self.peek().kind == SyntaxKind::TerminalElse {
1728 let else_kw = self.take::<TerminalElse>();
1729 let else_block_or_if = if self.peek().kind == SyntaxKind::TerminalIf {
1730 self.expect_if_expr().into()
1731 } else {
1732 self.parse_block().into()
1733 };
1734 ElseClause::new_green(self.db, else_kw, else_block_or_if).into()
1735 } else {
1736 OptionElseClauseEmpty::new_green(self.db).into()
1737 };
1738 ExprIf::new_green(self.db, if_kw, condition, if_block, else_clause)
1739 }
1740
1741 fn parse_condition_expr(&mut self) -> ConditionGreen {
1743 if self.peek().kind == SyntaxKind::TerminalLet {
1744 let let_kw = self.take::<TerminalLet>();
1745 let pattern_list = self
1746 .parse_separated_list_inner::<Pattern, TerminalOr, PatternListOrElementOrSeparatorGreen>(
1747 Self::try_parse_pattern,
1748 is_of_kind!(eq),
1749 "pattern",
1750 Some(ParserDiagnosticKind::DisallowedTrailingSeparatorOr),
1751 );
1752
1753 let pattern_list_green = if pattern_list.is_empty() {
1754 self.create_and_report_missing::<PatternListOr>(
1755 ParserDiagnosticKind::MissingPattern,
1756 )
1757 } else {
1758 PatternListOr::new_green(self.db, pattern_list)
1759 };
1760 let eq = self.parse_token::<TerminalEq>();
1761 let expr: ExprGreen = self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid);
1762 ConditionLet::new_green(self.db, let_kw, pattern_list_green, eq, expr).into()
1763 } else {
1764 let condition = self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid);
1765 ConditionExpr::new_green(self.db, condition).into()
1766 }
1767 }
1768
1769 fn expect_loop_expr(&mut self) -> ExprLoopGreen {
1772 let loop_kw = self.take::<TerminalLoop>();
1773 let body = self.parse_block();
1774
1775 ExprLoop::new_green(self.db, loop_kw, body)
1776 }
1777
1778 fn expect_while_expr(&mut self) -> ExprWhileGreen {
1781 let while_kw = self.take::<TerminalWhile>();
1782 let condition = self.parse_condition_expr();
1783 let body = self.parse_block();
1784
1785 ExprWhile::new_green(self.db, while_kw, condition, body)
1786 }
1787
1788 fn expect_for_expr(&mut self) -> ExprForGreen {
1792 let for_kw = self.take::<TerminalFor>();
1793 let pattern = self.parse_pattern();
1794 let ident = self.take_raw();
1795 let in_identifier: TerminalIdentifierGreen = match ident.text.as_str() {
1796 "in" => self.add_trivia_to_terminal::<TerminalIdentifier>(ident),
1797 _ => {
1798 self.append_skipped_token_to_pending_trivia(
1799 ident,
1800 ParserDiagnosticKind::SkippedElement { element_name: "'in'".into() },
1801 );
1802 TerminalIdentifier::missing(self.db)
1803 }
1804 };
1805 let expression = self.parse_expr_limited(MAX_PRECEDENCE, LbraceAllowed::Forbid);
1806 let body = self.parse_block();
1807 ExprFor::new_green(self.db, for_kw, pattern, in_identifier, expression, body)
1808 }
1809
1810 fn expect_closure_expr_nary(&mut self) -> ExprClosureGreen {
1813 let leftor = self.take::<TerminalOr>();
1814 let params = self.parse_closure_param_list();
1815 let rightor = self.parse_token::<TerminalOr>();
1816
1817 self.parse_closure_expr_body(
1818 ClosureParamWrapperNAry::new_green(self.db, leftor, params, rightor).into(),
1819 )
1820 }
1821 fn expect_closure_expr_nullary(&mut self) -> ExprClosureGreen {
1824 let wrapper = self.take::<TerminalOrOr>().into();
1825 self.parse_closure_expr_body(wrapper)
1826 }
1827 fn parse_closure_expr_body(&mut self, wrapper: ClosureParamWrapperGreen) -> ExprClosureGreen {
1828 let mut block_required = self.peek().kind == SyntaxKind::TerminalArrow;
1829
1830 let return_type_clause = self.parse_option_return_type_clause();
1831 let optional_no_panic = if self.peek().kind == SyntaxKind::TerminalNoPanic {
1832 block_required = true;
1833 self.take::<TerminalNoPanic>().into()
1834 } else {
1835 OptionTerminalNoPanicEmpty::new_green(self.db).into()
1836 };
1837 let expr = if block_required { self.parse_block().into() } else { self.parse_expr() };
1838
1839 ExprClosure::new_green(self.db, wrapper, return_type_clause, optional_no_panic, expr)
1840 }
1841
1842 fn expect_fixed_size_array_expr(&mut self) -> ExprFixedSizeArrayGreen {
1845 let lbrack = self.take::<TerminalLBrack>();
1846 let exprs: Vec<ExprListElementOrSeparatorGreen> = self
1847 .parse_separated_list::<Expr, TerminalComma, ExprListElementOrSeparatorGreen>(
1848 Self::try_parse_expr,
1849 is_of_kind!(rbrack, semicolon),
1850 "expression",
1851 );
1852 let size_green = if self.peek().kind == SyntaxKind::TerminalSemicolon {
1853 let semicolon = self.take::<TerminalSemicolon>();
1854 let size = self.parse_expr();
1855 FixedSizeArraySize::new_green(self.db, semicolon, size).into()
1856 } else {
1857 OptionFixedSizeArraySizeEmpty::new_green(self.db).into()
1858 };
1859 let rbrack = self.parse_token::<TerminalRBrack>();
1860 ExprFixedSizeArray::new_green(
1861 self.db,
1862 lbrack,
1863 ExprList::new_green(self.db, exprs),
1864 size_green,
1865 rbrack,
1866 )
1867 }
1868
1869 pub fn try_parse_match_arm(&mut self) -> TryParseResult<MatchArmGreen> {
1872 let pattern_list = self
1873 .parse_separated_list_inner::<Pattern, TerminalOr, PatternListOrElementOrSeparatorGreen>(
1874 Self::try_parse_pattern,
1875 is_of_kind!(match_arrow, rparen, block, rbrace, module_item_kw),
1876 "pattern",
1877 Some(ParserDiagnosticKind::DisallowedTrailingSeparatorOr),
1878 );
1879 if pattern_list.is_empty() {
1880 return Err(TryParseFailure::SkipToken);
1881 }
1882
1883 let pattern_list_green = PatternListOr::new_green(self.db, pattern_list);
1884
1885 let arrow = self.parse_token::<TerminalMatchArrow>();
1886 let expr = self.parse_expr();
1887 Ok(MatchArm::new_green(self.db, pattern_list_green, arrow, expr))
1888 }
1889
1890 fn try_parse_pattern(&mut self) -> TryParseResult<PatternGreen> {
1893 let modifier_list = self.parse_modifier_list();
1894 if !modifier_list.is_empty() {
1895 let modifiers = ModifierList::new_green(self.db, modifier_list);
1896 let name = self.parse_identifier();
1897 return Ok(PatternIdentifier::new_green(self.db, modifiers, name).into());
1898 };
1899
1900 Ok(match self.peek().kind {
1902 SyntaxKind::TerminalLiteralNumber => self.take_terminal_literal_number().into(),
1903 SyntaxKind::TerminalShortString => self.take_terminal_short_string().into(),
1904 SyntaxKind::TerminalTrue => self.take::<TerminalTrue>().into(),
1905 SyntaxKind::TerminalFalse => self.take::<TerminalFalse>().into(),
1906 SyntaxKind::TerminalUnderscore => self.take::<TerminalUnderscore>().into(),
1907 SyntaxKind::TerminalIdentifier => {
1908 let path = self.parse_path();
1911 match self.peek().kind {
1912 SyntaxKind::TerminalLBrace => {
1913 let lbrace = self.take::<TerminalLBrace>();
1914 let params = PatternStructParamList::new_green(
1915 self.db,
1916 self.parse_separated_list::<
1917 PatternStructParam,
1918 TerminalComma,
1919 PatternStructParamListElementOrSeparatorGreen>
1920 (
1921 Self::try_parse_pattern_struct_param,
1922 is_of_kind!(rparen, block, rbrace, module_item_kw),
1923 "struct pattern parameter",
1924 ),
1925 );
1926 let rbrace = self.parse_token::<TerminalRBrace>();
1927 PatternStruct::new_green(self.db, path, lbrace, params, rbrace).into()
1928 }
1929 SyntaxKind::TerminalLParen => {
1930 let lparen = self.take::<TerminalLParen>();
1932 let pattern = self.parse_pattern();
1933 let rparen = self.parse_token::<TerminalRParen>();
1934 let inner_pattern =
1935 PatternEnumInnerPattern::new_green(self.db, lparen, pattern, rparen);
1936 PatternEnum::new_green(self.db, path, inner_pattern.into()).into()
1937 }
1938 _ => {
1939 let green_node = path.0.lookup_intern(self.db);
1940 let children = match &green_node.details {
1941 GreenNodeDetails::Node { children, width: _ } => children,
1942 _ => return Err(TryParseFailure::SkipToken),
1943 };
1944 match children.len() {
1949 1 => path.into(),
1951 _ => PatternEnum::new_green(
1952 self.db,
1953 path,
1954 OptionPatternEnumInnerPatternEmpty::new_green(self.db).into(),
1955 )
1956 .into(),
1957 }
1958 }
1959 }
1960 }
1961 SyntaxKind::TerminalLParen => {
1962 let lparen = self.take::<TerminalLParen>();
1963 let patterns = PatternList::new_green(self.db, self.parse_separated_list::<
1964 Pattern,
1965 TerminalComma,
1966 PatternListElementOrSeparatorGreen>
1967 (
1968 Self::try_parse_pattern,
1969 is_of_kind!(rparen, block, rbrace, module_item_kw),
1970 "pattern",
1971 ));
1972 let rparen = self.parse_token::<TerminalRParen>();
1973 PatternTuple::new_green(self.db, lparen, patterns, rparen).into()
1974 }
1975 SyntaxKind::TerminalLBrack => {
1976 let lbrack = self.take::<TerminalLBrack>();
1977 let patterns = PatternList::new_green(self.db, self.parse_separated_list::<
1978 Pattern,
1979 TerminalComma,
1980 PatternListElementOrSeparatorGreen>
1981 (
1982 Self::try_parse_pattern,
1983 is_of_kind!(rbrack, block, rbrace, module_item_kw),
1984 "pattern",
1985 ));
1986 let rbrack = self.parse_token::<TerminalRBrack>();
1987 PatternFixedSizeArray::new_green(self.db, lbrack, patterns, rbrack).into()
1988 }
1989 _ => return Err(TryParseFailure::SkipToken),
1990 })
1991 }
1992 fn parse_pattern(&mut self) -> PatternGreen {
1995 match self.try_parse_pattern() {
1997 Ok(pattern) => pattern,
1998 Err(_) => self.create_and_report_missing_terminal::<TerminalUnderscore>().into(),
1999 }
2000 }
2001
2002 fn try_parse_pattern_struct_param(&mut self) -> TryParseResult<PatternStructParamGreen> {
2005 Ok(match self.peek().kind {
2006 SyntaxKind::TerminalDotDot => self.take::<TerminalDotDot>().into(),
2007 _ => {
2008 let modifier_list = self.parse_modifier_list();
2009 let name = if modifier_list.is_empty() {
2010 self.try_parse_identifier()?
2011 } else {
2012 self.parse_identifier()
2013 };
2014 let modifiers = ModifierList::new_green(self.db, modifier_list);
2015 if self.peek().kind == SyntaxKind::TerminalColon {
2016 let colon = self.take::<TerminalColon>();
2017 let pattern = self.parse_pattern();
2018 PatternStructParamWithExpr::new_green(self.db, modifiers, name, colon, pattern)
2019 .into()
2020 } else {
2021 PatternIdentifier::new_green(self.db, modifiers, name).into()
2022 }
2023 }
2024 })
2025 }
2026
2027 pub fn try_parse_statement(&mut self) -> TryParseResult<StatementGreen> {
2032 let maybe_attributes = self.try_parse_attribute_list("Statement");
2033 let (has_attrs, attributes) = match maybe_attributes {
2034 Ok(attributes) => (true, attributes),
2035 Err(_) => (false, AttributeList::new_green(self.db, vec![])),
2036 };
2037 match self.peek().kind {
2038 SyntaxKind::TerminalLet => {
2039 let let_kw = self.take::<TerminalLet>();
2040 let pattern = self.parse_pattern();
2041 let type_clause = self.parse_option_type_clause();
2042 let eq = self.parse_token::<TerminalEq>();
2043 let rhs = self.parse_expr();
2044 let semicolon = self.parse_token::<TerminalSemicolon>();
2045 Ok(StatementLet::new_green(
2046 self.db,
2047 attributes,
2048 let_kw,
2049 pattern,
2050 type_clause,
2051 eq,
2052 rhs,
2053 semicolon,
2054 )
2055 .into())
2056 }
2057 SyntaxKind::TerminalContinue => {
2058 let continue_kw = self.take::<TerminalContinue>();
2059 let semicolon = self.parse_token::<TerminalSemicolon>();
2060 Ok(StatementContinue::new_green(self.db, attributes, continue_kw, semicolon).into())
2061 }
2062 SyntaxKind::TerminalReturn => {
2063 let return_kw = self.take::<TerminalReturn>();
2064 let expr = self.parse_option_expression_clause();
2065 let semicolon = self.parse_token::<TerminalSemicolon>();
2066 Ok(StatementReturn::new_green(self.db, attributes, return_kw, expr, semicolon)
2067 .into())
2068 }
2069 SyntaxKind::TerminalBreak => {
2070 let break_kw = self.take::<TerminalBreak>();
2071 let expr = self.parse_option_expression_clause();
2072 let semicolon = self.parse_token::<TerminalSemicolon>();
2073 Ok(StatementBreak::new_green(self.db, attributes, break_kw, expr, semicolon).into())
2074 }
2075 SyntaxKind::TerminalConst => Ok(StatementItem::new_green(
2076 self.db,
2077 self.expect_item_const(attributes, VisibilityDefault::new_green(self.db).into())
2078 .into(),
2079 )
2080 .into()),
2081 SyntaxKind::TerminalUse => Ok(StatementItem::new_green(
2082 self.db,
2083 self.expect_item_use(attributes, VisibilityDefault::new_green(self.db).into())
2084 .into(),
2085 )
2086 .into()),
2087 SyntaxKind::TerminalType => Ok(StatementItem::new_green(
2088 self.db,
2089 self.expect_item_type_alias(
2090 attributes,
2091 VisibilityDefault::new_green(self.db).into(),
2092 )
2093 .into(),
2094 )
2095 .into()),
2096 _ => match self.try_parse_expr() {
2097 Ok(expr) => {
2098 let optional_semicolon = if self.peek().kind == SyntaxKind::TerminalSemicolon {
2099 self.take::<TerminalSemicolon>().into()
2100 } else {
2101 OptionTerminalSemicolonEmpty::new_green(self.db).into()
2102 };
2103 Ok(StatementExpr::new_green(self.db, attributes, expr, optional_semicolon)
2104 .into())
2105 }
2106 Err(_) if has_attrs => Ok(self.skip_taken_node_and_return_missing::<Statement>(
2107 attributes,
2108 ParserDiagnosticKind::AttributesWithoutStatement,
2109 )),
2110 Err(err) => Err(err),
2111 },
2112 }
2113 }
2114
2115 fn parse_option_type_clause(&mut self) -> OptionTypeClauseGreen {
2118 match self.try_parse_type_clause() {
2119 Some(green) => green.into(),
2120 None => OptionTypeClauseEmpty::new_green(self.db).into(),
2121 }
2122 }
2123
2124 fn parse_type_clause(&mut self, error_recovery: ErrorRecovery) -> TypeClauseGreen {
2126 match self.try_parse_type_clause() {
2127 Some(green) => green,
2128 None => {
2129 let res = self.create_and_report_missing::<TypeClause>(
2130 ParserDiagnosticKind::MissingTypeClause,
2131 );
2132 self.skip_until(error_recovery.should_stop).ok();
2133 res
2134 }
2135 }
2136 }
2137 fn try_parse_type_clause(&mut self) -> Option<TypeClauseGreen> {
2138 if self.peek().kind == SyntaxKind::TerminalColon {
2139 let colon = self.take::<TerminalColon>();
2140 let ty = self.parse_type_expr();
2141 Some(TypeClause::new_green(self.db, colon, ty))
2142 } else {
2143 None
2144 }
2145 }
2146
2147 fn parse_option_return_type_clause(&mut self) -> OptionReturnTypeClauseGreen {
2150 if self.peek().kind == SyntaxKind::TerminalArrow {
2151 let arrow = self.take::<TerminalArrow>();
2152 let return_type = self.parse_type_expr();
2153 ReturnTypeClause::new_green(self.db, arrow, return_type).into()
2154 } else {
2155 OptionReturnTypeClauseEmpty::new_green(self.db).into()
2156 }
2157 }
2158
2159 fn parse_option_implicits_clause(&mut self) -> OptionImplicitsClauseGreen {
2162 if self.peek().kind == SyntaxKind::TerminalImplicits {
2163 let implicits_kw = self.take::<TerminalImplicits>();
2164 let lparen = self.parse_token::<TerminalLParen>();
2165 let implicits = ImplicitsList::new_green(
2166 self.db,
2167 self.parse_separated_list::<ExprPath, TerminalComma, ImplicitsListElementOrSeparatorGreen>(
2168 Self::try_parse_path,
2169 is_of_kind!(rparen, lbrace, rbrace),
2171 "implicit type",
2172 ),
2173 );
2174 let rparen = self.parse_token::<TerminalRParen>();
2175 ImplicitsClause::new_green(self.db, implicits_kw, lparen, implicits, rparen).into()
2176 } else {
2177 OptionImplicitsClauseEmpty::new_green(self.db).into()
2178 }
2179 }
2180
2181 fn parse_param_list(&mut self) -> ParamListGreen {
2183 ParamList::new_green(
2184 self.db,
2185 self.parse_separated_list::<Param, TerminalComma, ParamListElementOrSeparatorGreen>(
2186 Self::try_parse_param,
2187 is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2188 "parameter",
2189 ),
2190 )
2191 }
2192
2193 fn parse_closure_param_list(&mut self) -> ParamListGreen {
2195 ParamList::new_green(
2196 self.db,
2197 self.parse_separated_list::<Param, TerminalComma, ParamListElementOrSeparatorGreen>(
2198 Self::try_parse_closure_param,
2199 is_of_kind!(or, block, lbrace, rbrace, module_item_kw),
2200 "parameter",
2201 ),
2202 )
2203 }
2204
2205 fn try_parse_modifier(&mut self) -> Option<ModifierGreen> {
2208 match self.peek().kind {
2209 SyntaxKind::TerminalRef => Some(self.take::<TerminalRef>().into()),
2210 SyntaxKind::TerminalMut => Some(self.take::<TerminalMut>().into()),
2211 _ => None,
2212 }
2213 }
2214
2215 fn parse_modifier_list(&mut self) -> Vec<ModifierGreen> {
2217 let mut modifier_list = vec![];
2218
2219 while let Some(modifier) = self.try_parse_modifier() {
2220 modifier_list.push(modifier);
2221 }
2222 modifier_list
2223 }
2224
2225 fn try_parse_param(&mut self) -> TryParseResult<ParamGreen> {
2228 let modifier_list = self.parse_modifier_list();
2229 let name = if modifier_list.is_empty() {
2230 self.try_parse_identifier()?
2231 } else {
2232 self.parse_identifier()
2234 };
2235
2236 let type_clause = self
2237 .parse_type_clause(ErrorRecovery {
2238 should_stop: is_of_kind!(comma, rparen, module_item_kw),
2239 })
2240 .into();
2241 Ok(Param::new_green(
2242 self.db,
2243 ModifierList::new_green(self.db, modifier_list),
2244 name,
2245 type_clause,
2246 ))
2247 }
2248
2249 fn try_parse_closure_param(&mut self) -> TryParseResult<ParamGreen> {
2252 let modifier_list = self.parse_modifier_list();
2253 let name = if modifier_list.is_empty() {
2254 self.try_parse_identifier()?
2255 } else {
2256 self.parse_identifier()
2258 };
2259
2260 let type_clause = self.parse_option_type_clause();
2261 Ok(Param::new_green(
2262 self.db,
2263 ModifierList::new_green(self.db, modifier_list),
2264 name,
2265 type_clause,
2266 ))
2267 }
2268
2269 fn parse_member_list(&mut self) -> MemberListGreen {
2271 MemberList::new_green(
2272 self.db,
2273 self.parse_separated_list::<Member, TerminalComma, MemberListElementOrSeparatorGreen>(
2274 Self::try_parse_member,
2275 is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2276 "member or variant",
2277 ),
2278 )
2279 }
2280
2281 fn try_parse_member(&mut self) -> TryParseResult<MemberGreen> {
2284 let attributes = self.try_parse_attribute_list("Struct member");
2285 let visibility = self.parse_visibility();
2286 let (name, attributes) = match attributes {
2287 Ok(attributes) => (self.parse_identifier(), attributes),
2288 Err(_) => (self.try_parse_identifier()?, AttributeList::new_green(self.db, vec![])),
2289 };
2290 let type_clause = self.parse_type_clause(ErrorRecovery {
2291 should_stop: is_of_kind!(comma, rbrace, module_item_kw),
2292 });
2293 Ok(Member::new_green(self.db, attributes, visibility, name, type_clause))
2294 }
2295
2296 fn parse_variant_list(&mut self) -> VariantListGreen {
2298 VariantList::new_green(
2299 self.db,
2300 self.parse_separated_list::<Variant, TerminalComma, VariantListElementOrSeparatorGreen>(
2301 Self::try_parse_variant,
2302 is_of_kind!(rparen, block, lbrace, rbrace, module_item_kw),
2303 "variant",
2304 ),
2305 )
2306 }
2307
2308 fn try_parse_variant(&mut self) -> TryParseResult<VariantGreen> {
2311 let attributes = self.try_parse_attribute_list("Enum variant");
2312 let (name, attributes) = match attributes {
2313 Ok(attributes) => (self.parse_identifier(), attributes),
2314 Err(_) => (self.try_parse_identifier()?, AttributeList::new_green(self.db, vec![])),
2315 };
2316
2317 let type_clause = self.parse_option_type_clause();
2318 Ok(Variant::new_green(self.db, attributes, name, type_clause))
2319 }
2320
2321 fn parse_path(&mut self) -> ExprPathGreen {
2324 let mut children: Vec<ExprPathElementOrSeparatorGreen> = vec![];
2325 loop {
2326 let (segment, optional_separator) = self.parse_path_segment();
2327 children.push(segment.into());
2328
2329 if let Some(separator) = optional_separator {
2330 children.push(separator.into());
2331 continue;
2332 }
2333 break;
2334 }
2335
2336 ExprPath::new_green(self.db, children)
2337 }
2338 fn try_parse_path(&mut self) -> TryParseResult<ExprPathGreen> {
2340 if self.is_peek_identifier_like() {
2341 Ok(self.parse_path())
2342 } else {
2343 Err(TryParseFailure::SkipToken)
2344 }
2345 }
2346
2347 fn parse_type_path(&mut self) -> ExprPathGreen {
2351 let mut children: Vec<ExprPathElementOrSeparatorGreen> = vec![];
2352 loop {
2353 let (segment, optional_separator) = self.parse_type_path_segment();
2354 children.push(segment.into());
2355
2356 if let Some(separator) = optional_separator {
2357 children.push(separator.into());
2358 continue;
2359 }
2360 break;
2361 }
2362
2363 ExprPath::new_green(self.db, children)
2364 }
2365
2366 fn parse_path_segment(&mut self) -> (PathSegmentGreen, Option<TerminalColonColonGreen>) {
2368 let identifier = match self.try_parse_identifier() {
2369 Ok(identifier) => identifier,
2370 Err(_) => {
2371 return (
2372 self.create_and_report_missing::<PathSegment>(
2373 ParserDiagnosticKind::MissingPathSegment,
2374 ),
2375 None,
2377 );
2378 }
2379 };
2380 match self.try_parse_token::<TerminalColonColon>() {
2381 Ok(separator) if self.peek().kind == SyntaxKind::TerminalLT => (
2382 PathSegmentWithGenericArgs::new_green(
2383 self.db,
2384 identifier,
2385 separator.into(),
2386 self.expect_generic_args(),
2387 )
2388 .into(),
2389 self.try_parse_token::<TerminalColonColon>().ok(),
2390 ),
2391 optional_separator => {
2392 (PathSegmentSimple::new_green(self.db, identifier).into(), optional_separator.ok())
2393 }
2394 }
2395 }
2396
2397 fn parse_type_path_segment(&mut self) -> (PathSegmentGreen, Option<TerminalColonColonGreen>) {
2400 let identifier = match self.try_parse_identifier() {
2401 Ok(identifier) => identifier,
2402 Err(_) => {
2403 return (
2404 self.create_and_report_missing::<PathSegment>(
2405 ParserDiagnosticKind::MissingPathSegment,
2406 ),
2407 None,
2409 );
2410 }
2411 };
2412 match self.try_parse_token::<TerminalColonColon>() {
2413 Err(_) if self.peek().kind == SyntaxKind::TerminalLT => (
2414 PathSegmentWithGenericArgs::new_green(
2415 self.db,
2416 identifier,
2417 OptionTerminalColonColonEmpty::new_green(self.db).into(),
2418 self.expect_generic_args(),
2419 )
2420 .into(),
2421 None,
2422 ),
2423 Ok(separator) if self.peek().kind == SyntaxKind::TerminalLT => (
2426 PathSegmentWithGenericArgs::new_green(
2427 self.db,
2428 identifier,
2429 separator.into(),
2430 self.expect_generic_args(),
2431 )
2432 .into(),
2433 self.try_parse_token::<TerminalColonColon>().ok(),
2434 ),
2435 optional_separator => {
2436 (PathSegmentSimple::new_green(self.db, identifier).into(), optional_separator.ok())
2437 }
2438 }
2439 }
2440
2441 fn take_terminal_literal_number(&mut self) -> TerminalLiteralNumberGreen {
2443 let text = self.peek().text.clone();
2444 let green = self.take::<TerminalLiteralNumber>();
2445 let span = TextSpan { start: self.offset, end: self.offset.add_width(self.current_width) };
2446
2447 validate_literal_number(self.diagnostics, text, span, self.file_id);
2448 green
2449 }
2450
2451 fn take_terminal_short_string(&mut self) -> TerminalShortStringGreen {
2453 let text = self.peek().text.clone();
2454 let green = self.take::<TerminalShortString>();
2455 let span = TextSpan { start: self.offset, end: self.offset.add_width(self.current_width) };
2456
2457 validate_short_string(self.diagnostics, text, span, self.file_id);
2458 green
2459 }
2460
2461 fn take_terminal_string(&mut self) -> TerminalStringGreen {
2463 let text = self.peek().text.clone();
2464 let green = self.take::<TerminalString>();
2465 let span = TextSpan { start: self.offset, end: self.offset.add_width(self.current_width) };
2466
2467 validate_string(self.diagnostics, text, span, self.file_id);
2468 green
2469 }
2470
2471 fn try_parse_generic_arg(&mut self) -> TryParseResult<GenericArgGreen> {
2475 if self.peek().kind == SyntaxKind::TerminalUnderscore {
2476 let underscore = self.take::<TerminalUnderscore>().into();
2477 return Ok(GenericArgUnnamed::new_green(self.db, underscore).into());
2478 }
2479
2480 let expr = match self.peek().kind {
2481 SyntaxKind::TerminalLiteralNumber => self.take_terminal_literal_number().into(),
2482 SyntaxKind::TerminalMinus => {
2483 let op = self.take::<TerminalMinus>().into();
2484 let expr = self.parse_token::<TerminalLiteralNumber>().into();
2485 ExprUnary::new_green(self.db, op, expr).into()
2486 }
2487 SyntaxKind::TerminalShortString => self.take_terminal_short_string().into(),
2488 SyntaxKind::TerminalTrue => self.take::<TerminalTrue>().into(),
2489 SyntaxKind::TerminalFalse => self.take::<TerminalFalse>().into(),
2490 SyntaxKind::TerminalLBrace => self.parse_block().into(),
2491 _ => self.try_parse_type_expr()?,
2492 };
2493
2494 if self.peek().kind == SyntaxKind::TerminalColon {
2497 if let Some(argname) = self.try_extract_identifier(expr) {
2498 let colon = self.take::<TerminalColon>();
2499 let expr = if self.peek().kind == SyntaxKind::TerminalUnderscore {
2500 self.take::<TerminalUnderscore>().into()
2501 } else {
2502 let expr = self.parse_type_expr();
2503 GenericArgValueExpr::new_green(self.db, expr).into()
2504 };
2505 return Ok(GenericArgNamed::new_green(self.db, argname, colon, expr).into());
2506 }
2507 }
2508 Ok(GenericArgUnnamed::new_green(
2509 self.db,
2510 GenericArgValueExpr::new_green(self.db, expr).into(),
2511 )
2512 .into())
2513 }
2514
2515 fn expect_generic_args(&mut self) -> GenericArgsGreen {
2518 let langle = self.take::<TerminalLT>();
2519 let generic_args = GenericArgList::new_green(
2520 self.db,
2521 self.parse_separated_list::<GenericArg, TerminalComma, GenericArgListElementOrSeparatorGreen>(
2522 Self::try_parse_generic_arg,
2523 is_of_kind!(rangle, rparen, block, lbrace, rbrace, module_item_kw),
2524 "generic arg",
2525 ),
2526 );
2527 let rangle = self.parse_token::<TerminalGT>();
2528 GenericArgs::new_green(self.db, langle, generic_args, rangle)
2529 }
2530
2531 fn expect_generic_params(&mut self) -> WrappedGenericParamListGreen {
2534 let langle = self.take::<TerminalLT>();
2535 let generic_params = GenericParamList::new_green(
2536 self.db,
2537 self.parse_separated_list::<GenericParam, TerminalComma, GenericParamListElementOrSeparatorGreen>(
2538 Self::try_parse_generic_param,
2539 is_of_kind!(rangle, rparen, block, lbrace, rbrace, module_item_kw),
2540 "generic param",
2541 ),
2542 );
2543 let rangle = self.parse_token::<TerminalGT>();
2544 WrappedGenericParamList::new_green(self.db, langle, generic_params, rangle)
2545 }
2546
2547 fn parse_optional_generic_params(&mut self) -> OptionWrappedGenericParamListGreen {
2548 if self.peek().kind != SyntaxKind::TerminalLT {
2549 return OptionWrappedGenericParamListEmpty::new_green(self.db).into();
2550 }
2551 self.expect_generic_params().into()
2552 }
2553
2554 fn try_parse_generic_param(&mut self) -> TryParseResult<GenericParamGreen> {
2555 match self.peek().kind {
2556 SyntaxKind::TerminalConst => {
2557 let const_kw = self.take::<TerminalConst>();
2558 let name = self.parse_identifier();
2559 let colon = self.parse_token::<TerminalColon>();
2560 let ty = self.parse_type_expr();
2561 Ok(GenericParamConst::new_green(self.db, const_kw, name, colon, ty).into())
2562 }
2563 SyntaxKind::TerminalImpl => {
2564 let impl_kw = self.take::<TerminalImpl>();
2565 let name = self.parse_identifier();
2566 let colon = self.parse_token::<TerminalColon>();
2567 let trait_path = self.parse_type_path();
2568 let associated_item_constraints = self.parse_optional_associated_item_constraints();
2569 Ok(GenericParamImplNamed::new_green(
2570 self.db,
2571 impl_kw,
2572 name,
2573 colon,
2574 trait_path,
2575 associated_item_constraints,
2576 )
2577 .into())
2578 }
2579 SyntaxKind::TerminalPlus => {
2580 let plus = self.take::<TerminalPlus>();
2581 let trait_path = self.parse_type_path();
2582 let associated_item_constraints = self.parse_optional_associated_item_constraints();
2583 Ok(GenericParamImplAnonymous::new_green(
2584 self.db,
2585 plus,
2586 trait_path,
2587 associated_item_constraints,
2588 )
2589 .into())
2590 }
2591 SyntaxKind::TerminalMinus => {
2592 let minus = self.take::<TerminalMinus>();
2593 let trait_path = self.parse_type_path();
2594 Ok(GenericParamNegativeImpl::new_green(self.db, minus, trait_path).into())
2595 }
2596 _ => Ok(GenericParamType::new_green(self.db, self.try_parse_identifier()?).into()),
2597 }
2598 }
2599
2600 fn expect_associated_item_constraints(&mut self) -> AssociatedItemConstraintsGreen {
2603 let lbrack = self.take::<TerminalLBrack>();
2604 let associated_item_constraints_list = AssociatedItemConstraintList::new_green(
2605 self.db,
2606 self.parse_separated_list::<AssociatedItemConstraint, TerminalComma, AssociatedItemConstraintListElementOrSeparatorGreen>(
2607 Self::try_parse_associated_item_constraint,
2608 is_of_kind!(rbrack,rangle, rparen, block, lbrace, rbrace, module_item_kw),
2609 "associated type argument",
2610 ),
2611 );
2612 let rangle = self.parse_token::<TerminalRBrack>();
2613 AssociatedItemConstraints::new_green(
2614 self.db,
2615 lbrack,
2616 associated_item_constraints_list,
2617 rangle,
2618 )
2619 }
2620
2621 fn parse_optional_associated_item_constraints(
2622 &mut self,
2623 ) -> OptionAssociatedItemConstraintsGreen {
2624 if self.peek().kind != SyntaxKind::TerminalLBrack {
2625 return OptionAssociatedItemConstraintsEmpty::new_green(self.db).into();
2626 }
2627 self.expect_associated_item_constraints().into()
2628 }
2629
2630 fn try_parse_associated_item_constraint(
2633 &mut self,
2634 ) -> TryParseResult<AssociatedItemConstraintGreen> {
2635 let ident = self.try_parse_identifier()?;
2636 let colon = self.parse_token::<TerminalColon>();
2637 let ty = self.parse_type_expr();
2638 Ok(AssociatedItemConstraint::new_green(self.db, ident, colon, ty))
2639 }
2640
2641 fn parse_list<ElementGreen>(
2653 &mut self,
2654 try_parse_list_element: fn(&mut Self) -> TryParseResult<ElementGreen>,
2655 should_stop: fn(SyntaxKind) -> bool,
2656 expected_element: &str,
2657 ) -> Vec<ElementGreen> {
2658 let mut children: Vec<ElementGreen> = Vec::new();
2659 loop {
2660 let parse_result = try_parse_list_element(self);
2661 match parse_result {
2662 Ok(element_green) => {
2663 children.push(element_green);
2664 }
2665 Err(err) => {
2666 if should_stop(self.peek().kind) {
2667 break;
2668 }
2669 if err == TryParseFailure::SkipToken {
2670 self.skip_token(ParserDiagnosticKind::SkippedElement {
2671 element_name: expected_element.into(),
2672 });
2673 }
2674 }
2675 }
2676 }
2677 children
2678 }
2679
2680 fn parse_attributed_list<ElementGreen>(
2691 &mut self,
2692 try_parse_list_element: fn(&mut Self) -> TryParseResult<ElementGreen>,
2693 should_stop: fn(SyntaxKind) -> bool,
2694 expected_element: &str,
2695 ) -> Vec<ElementGreen> {
2696 self.parse_list::<ElementGreen>(
2697 try_parse_list_element,
2698 should_stop,
2699 &or_an_attribute!(expected_element),
2700 )
2701 }
2702
2703 fn parse_separated_list_inner<
2720 Element: TypedSyntaxNode,
2721 Separator: syntax::node::Terminal,
2722 ElementOrSeparatorGreen,
2723 >(
2724 &mut self,
2725 try_parse_list_element: fn(&mut Self) -> TryParseResult<Element::Green>,
2726 should_stop: fn(SyntaxKind) -> bool,
2727 expected_element: &'static str,
2728 forbid_trailing_separator: Option<ParserDiagnosticKind>,
2729 ) -> Vec<ElementOrSeparatorGreen>
2730 where
2731 ElementOrSeparatorGreen: From<Separator::Green> + From<Element::Green>,
2732 {
2733 let mut children: Vec<ElementOrSeparatorGreen> = Vec::new();
2734 loop {
2735 match try_parse_list_element(self) {
2736 Err(_) if should_stop(self.peek().kind) => {
2737 if let (Some(diagnostic_kind), true) =
2738 (forbid_trailing_separator, !children.is_empty())
2739 {
2740 self.add_diagnostic(diagnostic_kind, TextSpan {
2741 start: self.offset,
2742 end: self.offset,
2743 });
2744 }
2745 break;
2746 }
2747 Err(_) => {
2748 self.skip_token(ParserDiagnosticKind::SkippedElement {
2749 element_name: expected_element.into(),
2750 });
2751 continue;
2752 }
2753 Ok(element) => {
2754 children.push(element.into());
2755 }
2756 };
2757
2758 let separator = match self.try_parse_token::<Separator>() {
2759 Err(_) if should_stop(self.peek().kind) => {
2760 break;
2761 }
2762 Err(_) => self.create_and_report_missing::<Separator>(
2763 ParserDiagnosticKind::MissingToken(Separator::KIND),
2764 ),
2765 Ok(separator) => separator,
2766 };
2767 children.push(separator.into());
2768 }
2769 children
2770 }
2771 fn parse_separated_list<
2773 Element: TypedSyntaxNode,
2774 Separator: syntax::node::Terminal,
2775 ElementOrSeparatorGreen,
2776 >(
2777 &mut self,
2778 try_parse_list_element: fn(&mut Self) -> TryParseResult<Element::Green>,
2779 should_stop: fn(SyntaxKind) -> bool,
2780 expected_element: &'static str,
2781 ) -> Vec<ElementOrSeparatorGreen>
2782 where
2783 ElementOrSeparatorGreen: From<Separator::Green> + From<Element::Green>,
2784 {
2785 self.parse_separated_list_inner::<Element, Separator, ElementOrSeparatorGreen>(
2786 try_parse_list_element,
2787 should_stop,
2788 expected_element,
2789 None,
2790 )
2791 }
2792
2793 fn peek(&self) -> &LexerTerminal {
2795 &self.next_terminal
2796 }
2797
2798 fn take_raw(&mut self) -> LexerTerminal {
2800 self.offset = self.offset.add_width(self.current_width);
2801 self.current_width = self.next_terminal.width(self.db);
2802 self.last_trivia_length = trivia_total_width(self.db, &self.next_terminal.trailing_trivia);
2803
2804 let next_terminal = self.lexer.next().unwrap();
2805 std::mem::replace(&mut self.next_terminal, next_terminal)
2806 }
2807
2808 fn skip_token(&mut self, diagnostic_kind: ParserDiagnosticKind) {
2812 if self.peek().kind == SyntaxKind::TerminalEndOfFile {
2813 self.add_diagnostic(diagnostic_kind, TextSpan { start: self.offset, end: self.offset });
2814 return;
2815 }
2816 let terminal = self.take_raw();
2817 self.append_skipped_token_to_pending_trivia(terminal, diagnostic_kind);
2818 }
2819
2820 fn append_skipped_token_to_pending_trivia(
2823 &mut self,
2824 terminal: LexerTerminal,
2825 diagnostic_kind: ParserDiagnosticKind,
2826 ) {
2827 let orig_offset = self.offset;
2828 let diag_start =
2829 self.offset.add_width(trivia_total_width(self.db, &terminal.leading_trivia));
2830 let diag_end = diag_start.add_width(TextWidth::from_str(&terminal.text));
2831
2832 self.pending_trivia.extend(terminal.leading_trivia.clone());
2834 self.pending_trivia.push(TokenSkipped::new_green(self.db, terminal.text).into());
2835 self.pending_trivia.extend(terminal.trailing_trivia.clone());
2836 self.pending_skipped_token_diagnostics.push(PendingParserDiagnostic {
2837 kind: diagnostic_kind,
2838 span: TextSpan { start: diag_start, end: diag_end },
2839 leading_trivia_start: orig_offset,
2840 trailing_trivia_end: diag_end
2841 .add_width(trivia_total_width(self.db, &terminal.trailing_trivia)),
2842 });
2843 }
2844
2845 fn skip_taken_node_from_current_offset(
2848 &mut self,
2849 node_to_skip: impl Into<SkippedNodeGreen>,
2850 diagnostic_kind: ParserDiagnosticKind,
2851 ) {
2852 self.skip_taken_node_with_offset(
2853 node_to_skip,
2854 diagnostic_kind,
2855 self.offset.add_width(self.current_width),
2856 )
2857 }
2858
2859 fn skip_taken_node_with_offset(
2865 &mut self,
2866 node_to_skip: impl Into<SkippedNodeGreen>,
2867 diagnostic_kind: ParserDiagnosticKind,
2868 end_of_node_offset: TextOffset,
2869 ) {
2870 let trivium_green = TriviumSkippedNode::new_green(self.db, node_to_skip.into()).into();
2871
2872 self.pending_trivia.push(trivium_green);
2874
2875 let start_of_node_offset = end_of_node_offset.sub_width(trivium_green.0.width(self.db));
2876 let diag_pos = end_of_node_offset
2877 .sub_width(trailing_trivia_width(self.db, trivium_green.0).unwrap_or_default());
2878
2879 self.pending_skipped_token_diagnostics.push(PendingParserDiagnostic {
2880 kind: diagnostic_kind,
2881 span: TextSpan { start: diag_pos, end: diag_pos },
2882 leading_trivia_start: start_of_node_offset,
2883 trailing_trivia_end: end_of_node_offset,
2884 });
2885 }
2886
2887 fn skip_token_and_return_missing<ExpectedTerminal: syntax::node::Terminal>(
2890 &mut self,
2891 diagnostic: ParserDiagnosticKind,
2892 ) -> ExpectedTerminal::Green {
2893 self.skip_token(diagnostic);
2894 ExpectedTerminal::missing(self.db)
2895 }
2896
2897 fn skip_taken_node_and_return_missing<ExpectedNode: TypedSyntaxNode>(
2900 &mut self,
2901 node_to_skip: impl Into<SkippedNodeGreen>,
2902 diagnostic_kind: ParserDiagnosticKind,
2903 ) -> ExpectedNode::Green {
2904 self.skip_taken_node_from_current_offset(node_to_skip, diagnostic_kind);
2905 ExpectedNode::missing(self.db)
2906 }
2907
2908 fn skip_until(&mut self, should_stop: fn(SyntaxKind) -> bool) -> Result<(), SkippedError> {
2912 let mut diag_start = None;
2913 let mut diag_end = None;
2914 while !should_stop(self.peek().kind) {
2915 let terminal = self.take_raw();
2916 diag_start.get_or_insert(self.offset);
2917 diag_end = Some(self.offset.add_width(TextWidth::from_str(&terminal.text)));
2918
2919 self.pending_trivia.extend(terminal.leading_trivia);
2920 self.pending_trivia.push(TokenSkipped::new_green(self.db, terminal.text).into());
2921 self.pending_trivia.extend(terminal.trailing_trivia);
2922 }
2923 if let (Some(diag_start), Some(diag_end)) = (diag_start, diag_end) {
2924 Err(SkippedError(TextSpan { start: diag_start, end: diag_end }))
2925 } else {
2926 Ok(())
2927 }
2928 }
2929
2930 fn add_trivia_to_terminal<Terminal: syntax::node::Terminal>(
2933 &mut self,
2934 lexer_terminal: LexerTerminal,
2935 ) -> Terminal::Green {
2936 let LexerTerminal { text, kind: _, leading_trivia, trailing_trivia } = lexer_terminal;
2937 let token = Terminal::TokenType::new_green(self.db, text);
2938 let mut new_leading_trivia = mem::take(&mut self.pending_trivia);
2939
2940 self.consume_pending_skipped_diagnostics();
2941
2942 new_leading_trivia.extend(leading_trivia);
2943 Terminal::new_green(
2944 self.db,
2945 Trivia::new_green(self.db, new_leading_trivia),
2946 token,
2947 Trivia::new_green(self.db, trailing_trivia),
2948 )
2949 }
2950
2951 fn consume_pending_skipped_diagnostics(&mut self) {
2954 let mut pending_skipped = self.pending_skipped_token_diagnostics.drain(..);
2955 let Some(first) = pending_skipped.next() else {
2956 return;
2957 };
2958
2959 let mut current_diag = first;
2960
2961 for diag in pending_skipped {
2962 if diag.kind == current_diag.kind
2963 && current_diag.trailing_trivia_end == diag.leading_trivia_start
2964 {
2965 current_diag = PendingParserDiagnostic {
2967 span: TextSpan { start: current_diag.span.start, end: diag.span.end },
2968 kind: diag.kind,
2969 leading_trivia_start: current_diag.leading_trivia_start,
2970 trailing_trivia_end: diag.trailing_trivia_end,
2971 };
2972 } else {
2973 self.diagnostics.add(ParserDiagnostic {
2976 file_id: self.file_id,
2977 span: current_diag.span,
2978 kind: current_diag.kind,
2979 });
2980 current_diag = diag;
2981 }
2982 }
2983 self.add_diagnostic(current_diag.kind, current_diag.span);
2985 }
2986
2987 fn take<Terminal: syntax::node::Terminal>(&mut self) -> Terminal::Green {
2990 let token = self.take_raw();
2991 assert_eq!(token.kind, Terminal::KIND);
2992 self.add_trivia_to_terminal::<Terminal>(token)
2993 }
2994
2995 fn take_doc(&mut self) -> Option<ItemHeaderDocGreen> {
2999 let mut has_header_doc = false;
3003 let mut split_index = 0;
3004 for trivium in self.next_terminal.leading_trivia.iter() {
3005 match trivium.0.lookup_intern(self.db).kind {
3006 SyntaxKind::TokenSingleLineComment | SyntaxKind::TokenSingleLineInnerComment => {
3007 has_header_doc = true;
3008 }
3009 SyntaxKind::TokenSingleLineDocComment => {
3010 break;
3011 }
3012 _ => {}
3013 }
3014 split_index += 1;
3015 }
3016 if !has_header_doc {
3017 return None;
3018 }
3019 let leading_trivia = self.next_terminal.leading_trivia.clone();
3021 let (header_doc, rest) = leading_trivia.split_at(split_index);
3022 self.next_terminal.leading_trivia = rest.to_vec();
3023 let empty_lexer_terminal = LexerTerminal {
3024 text: "".into(),
3025 kind: SyntaxKind::TerminalEmpty,
3026 leading_trivia: header_doc.to_vec(),
3027 trailing_trivia: vec![],
3028 };
3029 self.offset = self.offset.add_width(empty_lexer_terminal.width(self.db));
3030
3031 let empty_terminal = self.add_trivia_to_terminal::<TerminalEmpty>(empty_lexer_terminal);
3032 Some(ItemHeaderDoc::new_green(self.db, empty_terminal))
3033 }
3034
3035 fn try_parse_token<Terminal: syntax::node::Terminal>(
3040 &mut self,
3041 ) -> TryParseResult<Terminal::Green> {
3042 if Terminal::KIND == self.peek().kind {
3043 Ok(self.take::<Terminal>())
3044 } else {
3045 Err(TryParseFailure::SkipToken)
3046 }
3047 }
3048
3049 fn parse_token<Terminal: syntax::node::Terminal>(&mut self) -> Terminal::Green {
3055 self.parse_token_ex::<Terminal>(true)
3056 }
3057
3058 fn parse_token_ex<Terminal: syntax::node::Terminal>(
3060 &mut self,
3061 report_diagnostic: bool,
3062 ) -> Terminal::Green {
3063 match self.try_parse_token::<Terminal>() {
3064 Ok(green) => green,
3065 Err(_) => {
3066 if report_diagnostic {
3067 self.create_and_report_missing_terminal::<Terminal>()
3068 } else {
3069 Terminal::missing(self.db)
3070 }
3071 }
3072 }
3073 }
3074}
3075
3076#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3085enum LbraceAllowed {
3086 Forbid,
3087 Allow,
3088}
3089
3090struct SkippedError(TextSpan);
3092
3093struct ErrorRecovery {
3095 should_stop: fn(SyntaxKind) -> bool,
3098}
3099
3100enum ExternItem {
3101 Function(ItemExternFunctionGreen),
3102 Type(ItemExternTypeGreen),
3103}
3104
3105#[derive(Debug)]
3106enum ImplItemOrAlias {
3107 Item(ItemImplGreen),
3108 Alias(ItemImplAliasGreen),
3109}
3110
3111pub struct PendingParserDiagnostic {
3114 pub span: TextSpan,
3115 pub kind: ParserDiagnosticKind,
3116 pub leading_trivia_start: TextOffset,
3117 pub trailing_trivia_end: TextOffset,
3118}
3119
3120fn trivia_total_width(db: &dyn SyntaxGroup, trivia: &[TriviumGreen]) -> TextWidth {
3122 trivia.iter().map(|trivium| trivium.0.width(db)).sum::<TextWidth>()
3123}
3124
3125fn trailing_trivia_width(db: &dyn SyntaxGroup, green_id: GreenId) -> Option<TextWidth> {
3127 let node = green_id.lookup_intern(db);
3128 if node.kind == SyntaxKind::Trivia {
3129 return Some(node.width());
3130 }
3131 match &node.details {
3132 GreenNodeDetails::Token(_) => Some(TextWidth::default()),
3133 GreenNodeDetails::Node { children, .. } => {
3134 for child in children.iter().rev() {
3135 if let Some(width) = trailing_trivia_width(db, *child) {
3136 return Some(width);
3137 }
3138 }
3139 None
3140 }
3141 }
3142}