1use crate::{
4 Result,
5 ast::*,
6 ident::Ident,
7 parse::{Parse, ParseStream},
8 span::Span,
9 token::TokenKind,
10};
11
12impl Parse for CompilationUnit {
17 fn parse(input: &ParseStream) -> Result<Self> {
18 let mut package = None;
19 let mut imports = Vec::new();
20 let mut module = None;
21 let mut type_decls = Vec::new();
22
23 while !input.is_empty() {
24 if input.is(&TokenKind::Semicolon) {
25 input.collect_pending_comments();
27 let sp = input.peek().span;
28 input.next();
29 type_decls.push(TypeDecl::Empty(sp));
30 continue;
31 }
32 if input.is(&TokenKind::At) || input.is(&TokenKind::Package) {
33 let saved = input.cursor();
35 let pkg_result = input.try_parse(PackageDecl::parse);
36 if let Some(pkg) = pkg_result {
37 package = Some(pkg);
38 continue;
39 }
40 input.set_cursor(saved);
41 }
42 if input.is(&TokenKind::Import) {
43 imports.push(input.parse()?);
44 continue;
45 }
46 let doc_comment = input.collect_pending_doc_comments();
48 if input.is_ident("module") || input.is(&TokenKind::Open) {
49 let mut mod_decl: ModuleDecl = input.parse()?;
50 mod_decl.doc_comment = doc_comment;
51 module = Some(mod_decl);
52 continue;
53 }
54 let mut type_decl: TypeDecl = input.parse()?;
56 set_type_decl_doc_comment(&mut type_decl, doc_comment);
57 type_decls.push(type_decl);
58 }
59
60 let comments = input.collect_pending_comments();
62
63 Ok(Self {
64 comments,
65 package,
66 imports,
67 type_decls,
68 module,
69 })
70 }
71}
72
73fn set_type_decl_doc_comment(decl: &mut TypeDecl, doc_comment: Vec<Comment>) {
74 match decl {
75 TypeDecl::Class(c) => c.doc_comment = doc_comment,
76 TypeDecl::Interface(i) => i.doc_comment = doc_comment,
77 TypeDecl::Enum(e) => e.doc_comment = doc_comment,
78 TypeDecl::Record(r) => r.doc_comment = doc_comment,
79 TypeDecl::AnnotationType(a) => a.doc_comment = doc_comment,
80 TypeDecl::Empty(_) => {}
81 }
82}
83
84impl Parse for PackageDecl {
89 fn parse(input: &ParseStream) -> Result<Self> {
90 let start = input.peek().span;
91 let mut annotations = Vec::new();
92 while input.is(&TokenKind::At) {
93 annotations.push(input.parse::<Annotation>()?);
94 }
95 let package_span = input.peek().span;
96 input.expect(TokenKind::Package)?;
97 let name = parse_path(input)?;
98 input.expect(TokenKind::Semicolon)?;
99 let semi_span = input.peek().span;
100 Ok(Self {
101 annotations,
102 package_span,
103 name,
104 semi_span,
105 span: start.join(semi_span),
106 })
107 }
108}
109
110impl Parse for ImportDecl {
115 fn parse(input: &ParseStream) -> Result<Self> {
116 let import_span = input.peek().span;
117 input.expect(TokenKind::Import)?;
118
119 let is_static = input.eat(&TokenKind::Static);
120 let static_span = if is_static {
121 Some(input.peek().span)
122 } else {
123 None
124 };
125
126 let path = parse_path(input)?;
127
128 if input.eat(&TokenKind::Dot) && input.eat(&TokenKind::Star) {
129 let star_span = input.peek().span;
130 input.expect(TokenKind::Semicolon)?;
131 let semi_span = input.peek().span;
132 if is_static {
133 Ok(Self::StaticOnDemand {
134 import_span,
135 static_span: static_span.unwrap(),
136 path,
137 star_span,
138 semi_span,
139 })
140 } else {
141 Ok(Self::TypeOnDemand {
142 import_span,
143 path,
144 star_span,
145 semi_span,
146 })
147 }
148 } else {
149 input.expect(TokenKind::Semicolon)?;
150 let semi_span = input.peek().span;
151 if is_static {
152 let member = path.last_ident().clone();
153 Ok(Self::SingleStatic {
154 import_span,
155 static_span: static_span.unwrap(),
156 path,
157 member,
158 semi_span,
159 })
160 } else {
161 Ok(Self::SingleType {
162 import_span,
163 path,
164 semi_span,
165 })
166 }
167 }
168 }
169}
170
171impl Parse for ModuleDecl {
176 fn parse(input: &ParseStream) -> Result<Self> {
177 let mut annotations = Vec::new();
178 while input.is(&TokenKind::At) {
179 annotations.push(input.parse::<Annotation>()?);
180 }
181 let open_span = if input.eat(&TokenKind::Open) {
182 Some(input.peek().span)
183 } else {
184 None
185 };
186 let module_span = input.peek().span;
187 if !input.is_ident("module") {
188 return Err(crate::error::Error::new(
189 input.peek().span,
190 "expected 'module'",
191 ));
192 }
193 input.next();
194 let name = parse_path(input)?;
195 input.expect(TokenKind::LBrace)?;
196 let brace_start = input.peek().span;
197 let mut directives = Vec::new();
198 while !input.is(&TokenKind::RBrace) && !input.is_empty() {
199 directives.push(parse_module_directive(input)?);
200 }
201 input.expect(TokenKind::RBrace)?;
202 let brace_end = input.peek().span;
203 Ok(Self {
204 doc_comment: Vec::new(),
205 annotations,
206 open_span,
207 module_span,
208 name,
209 brace_span: (brace_start, brace_end),
210 directives,
211 })
212 }
213}
214
215fn parse_module_directive(input: &ParseStream) -> Result<ModuleDirective> {
216 let span = input.peek().span;
217 match &input.peek().kind {
218 TokenKind::Requires => {
219 input.next();
220 let requires_span = span;
221 let mut modifiers = Vec::new();
222 while input.is(&TokenKind::Transitive) {
223 modifiers.push(RequiresModifier::Transitive(input.next().span));
224 }
225 if input.is(&TokenKind::Static) {
226 modifiers.push(RequiresModifier::Static(input.next().span));
227 }
228 let module = parse_path(input)?;
229 input.expect(TokenKind::Semicolon)?;
230 let semi_span = input.peek().span;
231 Ok(ModuleDirective::Requires {
232 requires_span,
233 modifiers,
234 module,
235 semi_span,
236 })
237 }
238 TokenKind::Exports => {
239 input.next();
240 let exports_span = span;
241 let pkg = parse_path(input)?;
242 let to_modules = if input.eat(&TokenKind::To) {
243 let to_span = input.peek().span;
244 let mut mods = vec![parse_path(input)?];
245 while input.eat(&TokenKind::Comma) {
246 mods.push(parse_path(input)?);
247 }
248 Some((to_span, mods))
249 } else {
250 None
251 };
252 input.expect(TokenKind::Semicolon)?;
253 let semi_span = input.peek().span;
254 Ok(ModuleDirective::Exports {
255 exports_span,
256 pkg,
257 to_modules,
258 semi_span,
259 })
260 }
261 TokenKind::Opens => {
262 input.next();
263 let opens_span = span;
264 let pkg = parse_path(input)?;
265 let to_modules = if input.eat(&TokenKind::To) {
266 let to_span = input.peek().span;
267 let mut mods = vec![parse_path(input)?];
268 while input.eat(&TokenKind::Comma) {
269 mods.push(parse_path(input)?);
270 }
271 Some((to_span, mods))
272 } else {
273 None
274 };
275 input.expect(TokenKind::Semicolon)?;
276 let semi_span = input.peek().span;
277 Ok(ModuleDirective::Opens {
278 opens_span,
279 pkg,
280 to_modules,
281 semi_span,
282 })
283 }
284 TokenKind::Uses => {
285 input.next();
286 let uses_span = span;
287 let ty = parse_type(input)?;
288 input.expect(TokenKind::Semicolon)?;
289 let semi_span = input.peek().span;
290 Ok(ModuleDirective::Uses {
291 uses_span,
292 ty,
293 semi_span,
294 })
295 }
296 TokenKind::Provides => {
297 input.next();
298 let provides_span = span;
299 let ty = parse_type(input)?;
300 input.expect(TokenKind::With)?;
301 let with_span = input.peek().span;
302 let mut impls = vec![parse_type(input)?];
303 while input.eat(&TokenKind::Comma) {
304 impls.push(parse_type(input)?);
305 }
306 input.expect(TokenKind::Semicolon)?;
307 let semi_span = input.peek().span;
308 Ok(ModuleDirective::Provides {
309 provides_span,
310 ty,
311 with_span,
312 impls,
313 semi_span,
314 })
315 }
316 _ => Err(crate::error::Error::new(span, "expected module directive")),
317 }
318}
319
320impl Parse for TypeDecl {
325 fn parse(input: &ParseStream) -> Result<Self> {
326 let annotations = parse_annotations(input)?;
327 let modifiers = parse_modifiers_after_annotations(&annotations, input);
328
329 match &input.peek().kind {
330 TokenKind::Class => {
331 let decl: ClassDecl = parse_class_decl(input, Vec::new(), modifiers)?;
332 Ok(Self::Class(decl))
333 }
334 TokenKind::Interface => {
335 let decl: InterfaceDecl = parse_interface_decl(input, Vec::new(), modifiers)?;
336 Ok(Self::Interface(decl))
337 }
338 TokenKind::Enum => {
339 let decl: EnumDecl = parse_enum_decl(input, Vec::new(), modifiers)?;
340 Ok(Self::Enum(decl))
341 }
342 TokenKind::Record => {
343 let decl: RecordDecl = parse_record_decl(input, Vec::new(), modifiers)?;
344 Ok(Self::Record(decl))
345 }
346 TokenKind::At => {
347 let saved = input.cursor();
349 let at_span = input.peek().span;
350 input.next(); if input.is(&TokenKind::Interface) {
352 input.next(); let name = input.parse_ident()?;
354 let body = parse_annotation_type_body(input)?;
355 return Ok(Self::AnnotationType(AnnotationInterfaceDecl {
356 doc_comment: Vec::new(),
357 modifiers,
358 at_span,
359 interface_span: name.span(),
360 name,
361 body,
362 }));
363 }
364 input.set_cursor(saved);
365
366 let mut all_mods = modifiers.clone();
368 let ann = input.parse::<Annotation>()?;
369 all_mods.push(Modifier::Annotation(ann));
370 match &input.peek().kind {
371 TokenKind::Class => {
372 let decl = parse_class_decl(input, Vec::new(), all_mods)?;
373 Ok(Self::Class(decl))
374 }
375 TokenKind::Interface => {
376 let decl = parse_interface_decl(input, Vec::new(), all_mods)?;
377 Ok(Self::Interface(decl))
378 }
379 TokenKind::Enum => {
380 let decl = parse_enum_decl(input, Vec::new(), all_mods)?;
381 Ok(Self::Enum(decl))
382 }
383 TokenKind::Record => {
384 let decl = parse_record_decl(input, Vec::new(), all_mods)?;
385 Ok(Self::Record(decl))
386 }
387 _ => Err(crate::error::Error::new(
388 input.peek().span,
389 "expected type declaration",
390 )),
391 }
392 }
393 _ => Err(crate::error::Error::new(
394 input.peek().span,
395 "expected type declaration (class, interface, enum, or record)",
396 )),
397 }
398 }
399}
400
401fn parse_annotations(input: &ParseStream) -> Result<Vec<Annotation>> {
406 let mut anns = Vec::new();
407 while input.is(&TokenKind::At) {
408 let saved = input.cursor();
410 input.next(); if input.is(&TokenKind::Interface) {
412 input.set_cursor(saved);
413 break;
414 }
415 input.set_cursor(saved);
416 anns.push(input.parse::<Annotation>()?);
417 }
418 Ok(anns)
419}
420
421fn is_modifier_keyword(kind: &TokenKind) -> bool {
422 matches!(
423 kind,
424 TokenKind::Public
425 | TokenKind::Protected
426 | TokenKind::Private
427 | TokenKind::Static
428 | TokenKind::Abstract
429 | TokenKind::Final
430 | TokenKind::Synchronized
431 | TokenKind::Native
432 | TokenKind::Strictfp
433 | TokenKind::Transient
434 | TokenKind::Volatile
435 | TokenKind::Default
436 | TokenKind::Sealed
437 | TokenKind::NonSealed
438 )
439}
440
441fn parse_modifier(input: &ParseStream) -> Option<Modifier> {
442 let modifier = match &input.peek().kind {
443 TokenKind::Public => Modifier::Public(input.next().span),
444 TokenKind::Protected => Modifier::Protected(input.next().span),
445 TokenKind::Private => Modifier::Private(input.next().span),
446 TokenKind::Static => Modifier::Static(input.next().span),
447 TokenKind::Abstract => Modifier::Abstract(input.next().span),
448 TokenKind::Final => Modifier::Final(input.next().span),
449 TokenKind::Synchronized => Modifier::Synchronized(input.next().span),
450 TokenKind::Native => Modifier::Native(input.next().span),
451 TokenKind::Strictfp => Modifier::Strictfp(input.next().span),
452 TokenKind::Transient => Modifier::Transient(input.next().span),
453 TokenKind::Volatile => Modifier::Volatile(input.next().span),
454 TokenKind::Default => Modifier::Default(input.next().span),
455 TokenKind::Sealed => Modifier::Sealed(input.next().span),
456 TokenKind::NonSealed => Modifier::NonSealed(input.next().span),
457 TokenKind::Ident(s) if s == "non" => {
458 let saved = input.cursor();
460 let non_span = input.next().span;
461 if input.eat(&TokenKind::Minus) && input.is(&TokenKind::Sealed) {
462 let sealed_span = input.next().span;
463 Modifier::NonSealed(non_span.join(sealed_span))
464 } else {
465 input.set_cursor(saved);
466 return None;
467 }
468 }
469 TokenKind::At => {
470 let ann = input.try_parse(Annotation::parse);
471 match ann {
472 Some(a) => Modifier::Annotation(a),
473 None => return None,
474 }
475 }
476 _ => return None,
477 };
478 Some(modifier)
479}
480
481fn parse_modifiers(input: &ParseStream) -> Vec<Modifier> {
482 let mut mods = Vec::new();
483 while let Some(m) = parse_modifier(input) {
484 mods.push(m);
485 }
486 mods
487}
488
489fn parse_modifiers_after_annotations(
490 annotations: &[Annotation],
491 input: &ParseStream,
492) -> Vec<Modifier> {
493 let mut mods: Vec<Modifier> = annotations
494 .iter()
495 .map(|a| Modifier::Annotation(a.clone()))
496 .collect();
497 while let Some(m) = parse_modifier(input) {
498 mods.push(m);
499 }
500 mods
501}
502
503impl Parse for Annotation {
508 fn parse(input: &ParseStream) -> Result<Self> {
509 let at_token = input.peek().span;
510 input.expect(TokenKind::At)?;
511 let name = parse_annotation_path(input)?;
512
513 if input.is(&TokenKind::LParen) {
514 input.next();
515 let open = input.peek().span;
516
517 if input.is(&TokenKind::RParen) {
518 input.next();
519 return Ok(Self::Marker { at_token, name });
520 }
521
522 if input.is_any_ident() {
525 let saved = input.cursor();
526 let ident = input.parse_ident().ok();
527 if let Some(ident) = ident {
528 if input.eat(&TokenKind::Eq) {
529 let eq_span = input.peek().span;
531 let value = parse_element_value(input)?;
532 let mut pairs = vec![ElementValuePair {
533 key: ident,
534 eq_span,
535 value,
536 }];
537 while input.eat(&TokenKind::Comma) {
538 let key = input.parse_ident()?;
539 input.expect(TokenKind::Eq)?;
540 let eq_span = input.peek().span;
541 let value = parse_element_value(input)?;
542 pairs.push(ElementValuePair {
543 key,
544 eq_span,
545 value,
546 });
547 }
548 input.expect(TokenKind::RParen)?;
549 let close = input.peek().span;
550 return Ok(Self::Normal {
551 at_token,
552 name,
553 paren_span: (open, close),
554 pairs,
555 });
556 } else {
557 input.set_cursor(saved);
559 }
560 } else {
561 input.set_cursor(saved);
562 }
563 }
564
565 let value = parse_element_value(input)?;
567 input.expect(TokenKind::RParen)?;
568 let eq_token = input.peek().span;
569 Ok(Self::SingleElement {
570 at_token,
571 name,
572 eq_token,
573 value: Box::new(value),
574 })
575 } else {
576 Ok(Self::Marker { at_token, name })
577 }
578 }
579}
580
581fn parse_element_value(input: &ParseStream) -> Result<ElementValue> {
582 if input.is(&TokenKind::At) {
583 let ann = input.parse::<Annotation>()?;
584 Ok(ElementValue::Annotation(ann))
585 } else if input.is(&TokenKind::LBrace) {
586 let open = input.peek().span;
587 input.next();
588 let mut values = Vec::new();
589 let mut trailing_comma = false;
590 while !input.is(&TokenKind::RBrace) && !input.is_empty() {
591 values.push(parse_element_value(input)?);
592 if input.eat(&TokenKind::Comma) {
593 trailing_comma = true;
594 } else {
595 trailing_comma = false;
596 break;
597 }
598 }
599 input.expect(TokenKind::RBrace)?;
600 let close = input.peek().span;
601 Ok(ElementValue::Array {
602 brace_span: (open, close),
603 values,
604 trailing_comma,
605 })
606 } else {
607 let expr = parse_expression(input)?;
608 Ok(ElementValue::Expr(expr))
609 }
610}
611
612fn parse_implements_clause(input: &ParseStream) -> Option<ImplementsClause> {
613 if input.eat(&TokenKind::Implements) {
614 let implements_span = input.peek().span;
615 let supertypes = parse_type_list(input);
616 Some(ImplementsClause {
617 implements_span,
618 supertypes,
619 })
620 } else {
621 None
622 }
623}
624
625fn parse_array_init(input: &ParseStream) -> Result<ArrayInitExpr> {
626 let open = input.peek().span;
627 input.next();
628 let mut elements = Vec::new();
629 let mut trailing_comma = false;
630 while !input.is(&TokenKind::RBrace) && !input.is_empty() {
631 elements.push(parse_expression(input)?);
632 if input.eat(&TokenKind::Comma) {
633 trailing_comma = true;
634 } else {
635 trailing_comma = false;
636 break;
637 }
638 }
639 input.expect(TokenKind::RBrace)?;
640 let close = input.peek().span;
641 Ok(ArrayInitExpr {
642 brace_span: (open, close),
643 elements,
644 trailing_comma,
645 })
646}
647
648fn parse_class_decl(
653 input: &ParseStream,
654 doc_comment: Vec<Comment>,
655 modifiers: Vec<Modifier>,
656) -> Result<ClassDecl> {
657 let class_span = input.peek().span;
658 input.expect(TokenKind::Class)?;
659 let name = input.parse_ident()?;
660 let type_params = parse_optional_type_params(input);
661 let extends_clause = if input.eat(&TokenKind::Extends) {
662 let extends_span = input.peek().span;
663 let supertype = parse_type(input)?;
664 Some(ExtendsClause {
665 extends_span,
666 supertype,
667 })
668 } else {
669 None
670 };
671 let implements_clause = parse_implements_clause(input);
672 let permits_clause = if input.eat(&TokenKind::Permits) {
673 let permits_span = input.peek().span;
674 let types = parse_type_list(input);
675 Some(PermitsClause {
676 permits_span,
677 types,
678 })
679 } else {
680 None
681 };
682 let body = parse_class_body_decl_list(input)?;
683 Ok(ClassDecl {
684 doc_comment,
685 modifiers,
686 class_span,
687 name,
688 type_params,
689 extends_clause,
690 implements_clause,
691 permits_clause,
692 body,
693 })
694}
695
696fn parse_class_body_decl_list(input: &ParseStream) -> Result<ClassBodyDeclList> {
697 input.expect(TokenKind::LBrace)?;
698 let open = input.peek().span;
699 let mut declarations = Vec::new();
700 while !input.is_empty() {
701 if input.is(&TokenKind::RBrace) {
702 break;
703 }
704 if input.is(&TokenKind::Semicolon) {
705 let sp = input.next().span;
706 declarations.push(ClassBodyDecl::Empty(sp));
707 continue;
708 }
709 declarations.push(parse_class_body_decl(input)?);
710 }
711 let close = input.peek().span;
712 input.expect(TokenKind::RBrace)?;
713 Ok(ClassBodyDeclList {
714 brace_span: (open, close),
715 declarations,
716 })
717}
718
719fn parse_class_body_decl(input: &ParseStream) -> Result<ClassBodyDecl> {
720 let doc_comment = input.collect_pending_doc_comments();
721 let modifiers = parse_modifiers(input);
722
723 match &input.peek().kind {
724 TokenKind::LBrace => {
725 let block = parse_block(input, Vec::new())?;
726 Ok(ClassBodyDecl::InstanceInit(InstanceInit { block }))
727 }
728 TokenKind::Static => {
729 let static_span = input.peek().span;
731 input.next();
732 if input.is(&TokenKind::LBrace) {
733 let block = parse_block(input, Vec::new())?;
734 Ok(ClassBodyDecl::StaticInit(StaticInit { static_span, block }))
735 } else {
736 let mut rest_mods = modifiers;
737 rest_mods.push(Modifier::Static(static_span));
738 let rest = parse_modifiers(input);
739 rest_mods.extend(rest);
740 parse_class_member(input, doc_comment.clone(), rest_mods)
741 }
742 }
743 TokenKind::Class => {
744 let decl = parse_class_decl(input, doc_comment, modifiers)?;
745 Ok(ClassBodyDecl::Class(decl))
746 }
747 TokenKind::Interface => {
748 let decl = parse_interface_decl(input, doc_comment, modifiers)?;
749 Ok(ClassBodyDecl::Interface(decl))
750 }
751 TokenKind::Enum => {
752 let decl = parse_enum_decl(input, doc_comment, modifiers)?;
753 Ok(ClassBodyDecl::Enum(decl))
754 }
755 TokenKind::Record => {
756 let decl = parse_record_decl(input, doc_comment, modifiers)?;
757 Ok(ClassBodyDecl::Record(decl))
758 }
759 TokenKind::At => {
760 let saved = input.cursor();
762 let at_span = input.peek().span;
763 input.next(); if input.is(&TokenKind::Interface) {
765 input.next(); let name = input.parse_ident()?;
767 let body = parse_annotation_type_body(input)?;
768 Ok(ClassBodyDecl::AnnotationType(AnnotationInterfaceDecl {
769 doc_comment,
770 modifiers,
771 at_span,
772 interface_span: name.span(),
773 name,
774 body,
775 }))
776 } else {
777 input.set_cursor(saved);
778 parse_class_member(input, doc_comment.clone(), modifiers)
779 }
780 }
781 _ => parse_class_member(input, doc_comment, modifiers),
782 }
783}
784
785fn parse_class_member(
786 input: &ParseStream,
787 doc_comment: Vec<Comment>,
788 modifiers: Vec<Modifier>,
789) -> Result<ClassBodyDecl> {
790 let type_params = parse_optional_type_params(input);
791
792 let ty = parse_type(input)?;
794
795 if input.is(&TokenKind::LParen) {
796 let name = match &ty {
798 Type::Reference(ReferenceType::ClassOrInterfaceType(cit)) => cit.name().clone(),
799 _ => {
800 return Err(crate::error::Error::new(
801 input.peek().span,
802 "expected constructor name",
803 ));
804 }
805 };
806 input.expect(TokenKind::LParen)?;
807 let open = input.peek().span;
808 let params = parse_formal_params_after_lparen(input)?;
809 let throws_clause = parse_throws_clause(input)?;
810 let body = parse_constructor_body(input)?;
811 return Ok(ClassBodyDecl::Constructor(ConstructorDecl {
812 doc_comment,
813 modifiers,
814 type_params,
815 name,
816 receiver_param: None,
817 params,
818 paren_span: (open, input.peek().span),
819 throws_clause,
820 body,
821 }));
822 }
823
824 if input.is_any_ident() {
825 let name = input.parse_ident()?;
826
827 if input.is(&TokenKind::LParen) {
828 input.expect(TokenKind::LParen)?;
830 let open = input.peek().span;
831 let params = parse_formal_params_after_lparen(input)?;
832 let _trailing_dims = parse_array_dims(input)?;
834 let throws_clause = parse_throws_clause(input)?;
835 let body = if input.is(&TokenKind::LBrace) {
836 Some(parse_block(input, Vec::new())?)
837 } else {
838 input.expect(TokenKind::Semicolon)?;
839 None
840 };
841 return Ok(ClassBodyDecl::Method(MethodDecl {
842 doc_comment,
843 modifiers,
844 type_params,
845 return_type: ty.into(),
846 name,
847 receiver_param: None,
848 params,
849 paren_span: (open, input.peek().span),
850 throws_clause,
851 body,
852 }));
853 }
854
855 let dims = parse_array_dims(input)?;
857 let mut declarators = Vec::new();
858 let initializer = if input.eat(&TokenKind::Eq) {
859 Some(parse_expression(input)?)
860 } else {
861 None
862 };
863 declarators.push(VariableDeclarator {
864 name: Some(name),
865 dims,
866 initializer,
867 });
868 while input.eat(&TokenKind::Comma) {
869 let name = input.parse_ident()?;
870 let dims = parse_array_dims(input)?;
871 let initializer = if input.eat(&TokenKind::Eq) {
872 Some(parse_expression(input)?)
873 } else {
874 None
875 };
876 declarators.push(VariableDeclarator {
877 name: Some(name),
878 dims,
879 initializer,
880 });
881 }
882 input.expect(TokenKind::Semicolon)?;
883 let semi_span = input.peek().span;
884 return Ok(ClassBodyDecl::Field(FieldDecl {
885 doc_comment,
886 modifiers,
887 ty,
888 declarators,
889 semi_span,
890 }));
891 }
892
893 Err(crate::error::Error::new(
894 input.peek().span,
895 "expected method or field declaration",
896 ))
897}
898
899fn parse_formal_params_after_lparen(input: &ParseStream) -> Result<Vec<FormalParameter>> {
900 let mut params = Vec::new();
901 while !input.is(&TokenKind::RParen) && !input.is_empty() {
902 let modifiers = parse_modifiers(input);
903 let ty = parse_type(input)?;
904 let name = if input.is(&TokenKind::This) {
906 let sp = input.next().span;
907 Some(Ident::new("this".to_string(), sp))
908 } else {
909 input.parse_ident().ok()
910 };
911
912 let ty = if name.is_some() && input.is(&TokenKind::LBracket) {
914 let trailing_dims = parse_array_dims(input)?;
915 if trailing_dims.is_empty() {
916 ty
917 } else {
918 let start = ty.span();
919 let end = trailing_dims.last().unwrap().bracket_span.1;
920 let span = start.join(end);
921 let mut all_dims = trailing_dims;
922 if let Type::Reference(ReferenceType::Array(arr)) = &ty {
924 let mut merged = arr.dims.clone();
925 merged.extend(all_dims);
926 all_dims = merged;
927 }
928 Type::Reference(ReferenceType::Array(ArrayType {
929 elem_type: Box::new(match &ty {
930 Type::Reference(ReferenceType::Array(arr)) => *arr.elem_type.clone(),
931 other => other.clone(),
932 }),
933 dims: all_dims,
934 span,
935 }))
936 }
937 } else {
938 ty
939 };
940
941 if input.eat(&TokenKind::Ellipsis) {
942 let ellipsis_span = input.peek().span;
943 let name = input.parse_ident().ok();
944 params.push(FormalParameter::VarArgs {
945 modifiers,
946 ty,
947 ellipsis_span,
948 name,
949 });
950 } else {
951 params.push(FormalParameter::Normal {
952 modifiers,
953 ty,
954 name,
955 });
956 }
957 if !input.eat(&TokenKind::Comma) {
958 break;
959 }
960 }
961 input.expect(TokenKind::RParen)?;
962 Ok(params)
963}
964
965fn parse_throws_clause(input: &ParseStream) -> Result<Option<ThrowsClause>> {
966 if input.eat(&TokenKind::Throws) {
967 let throws_span = input.peek().span;
968 let types = parse_type_list(input);
969 Ok(Some(ThrowsClause { throws_span, types }))
970 } else {
971 Ok(None)
972 }
973}
974
975fn parse_interface_decl(
980 input: &ParseStream,
981 doc_comment: Vec<Comment>,
982 modifiers: Vec<Modifier>,
983) -> Result<InterfaceDecl> {
984 let interface_span = input.peek().span;
985 input.expect(TokenKind::Interface)?;
986 let name = input.parse_ident()?;
987 let type_params = parse_optional_type_params(input);
988 let extends_clause = if input.eat(&TokenKind::Extends) {
989 let extends_span = input.peek().span;
990 let supertypes = parse_type_list(input);
991 Some(InterfaceExtendsClause {
992 extends_span,
993 supertypes,
994 })
995 } else {
996 None
997 };
998 let permits_clause = if input.eat(&TokenKind::Permits) {
999 let permits_span = input.peek().span;
1000 let types = parse_type_list(input);
1001 Some(PermitsClause {
1002 permits_span,
1003 types,
1004 })
1005 } else {
1006 None
1007 };
1008
1009 input.expect(TokenKind::LBrace)?;
1012 let open = input.peek().span;
1013 let mut members = Vec::new();
1014 while !input.is_empty() {
1015 if input.is(&TokenKind::RBrace) {
1016 break;
1017 }
1018 if input.is(&TokenKind::Semicolon) {
1019 let sp = input.next().span;
1020 members.push(InterfaceMemberDecl::Empty(sp));
1021 continue;
1022 }
1023 members.push(parse_interface_member_decl(input)?);
1024 }
1025 input.expect(TokenKind::RBrace)?;
1026 let close = input.peek().span;
1027
1028 Ok(InterfaceDecl {
1029 doc_comment,
1030 modifiers,
1031 interface_span,
1032 name,
1033 type_params,
1034 extends_clause,
1035 permits_clause,
1036 body: InterfaceBody {
1037 brace_span: (open, close),
1038 members,
1039 },
1040 })
1041}
1042
1043fn parse_interface_member_decl(input: &ParseStream) -> Result<InterfaceMemberDecl> {
1044 let doc_comment = input.collect_pending_doc_comments();
1045 let modifiers = parse_modifiers(input);
1046
1047 match &input.peek().kind {
1048 TokenKind::Class => {
1049 let decl = parse_class_decl(input, doc_comment, modifiers)?;
1050 Ok(InterfaceMemberDecl::Class(decl))
1051 }
1052 TokenKind::Interface => {
1053 let decl = parse_interface_decl(input, doc_comment, modifiers)?;
1054 Ok(InterfaceMemberDecl::Interface(decl))
1055 }
1056 TokenKind::Enum => {
1057 let decl = parse_enum_decl(input, doc_comment, modifiers)?;
1058 Ok(InterfaceMemberDecl::Enum(decl))
1059 }
1060 TokenKind::Record => {
1061 let decl = parse_record_decl(input, doc_comment, modifiers)?;
1062 Ok(InterfaceMemberDecl::Record(decl))
1063 }
1064 TokenKind::At => {
1065 let saved = input.cursor();
1067 let at_span = input.peek().span;
1068 input.next(); if input.is(&TokenKind::Interface) {
1070 input.next(); let name = input.parse_ident()?;
1072 let body = parse_annotation_type_body(input)?;
1073 Ok(InterfaceMemberDecl::AnnotationInterface(
1074 AnnotationInterfaceDecl {
1075 doc_comment,
1076 modifiers,
1077 at_span,
1078 interface_span: name.span(),
1079 name,
1080 body,
1081 },
1082 ))
1083 } else {
1084 input.set_cursor(saved);
1085 parse_interface_field_or_method(input, doc_comment, modifiers)
1086 }
1087 }
1088 _ => parse_interface_field_or_method(input, doc_comment, modifiers),
1089 }
1090}
1091
1092fn parse_interface_field_or_method(
1093 input: &ParseStream,
1094 doc_comment: Vec<Comment>,
1095 modifiers: Vec<Modifier>,
1096) -> Result<InterfaceMemberDecl> {
1097 let type_params = parse_optional_type_params(input);
1098 let ty = parse_type(input)?;
1099 if input.is_any_ident() {
1100 let name = input.parse_ident()?;
1101 if input.is(&TokenKind::LParen) {
1102 input.expect(TokenKind::LParen)?;
1104 let open = input.peek().span;
1105 let params = parse_formal_params_after_lparen(input)?;
1106 let throws_clause = parse_throws_clause(input)?;
1107 let body = if input.is(&TokenKind::LBrace) {
1108 Some(parse_block(input, Vec::new())?)
1109 } else {
1110 input.expect(TokenKind::Semicolon)?;
1111 None
1112 };
1113 Ok(InterfaceMemberDecl::Method(MethodDecl {
1114 doc_comment,
1115 modifiers,
1116 type_params,
1117 return_type: ty.into(),
1118 name,
1119 receiver_param: None,
1120 params,
1121 paren_span: (open, input.peek().span),
1122 throws_clause,
1123 body,
1124 }))
1125 } else {
1126 let dims = parse_array_dims(input)?;
1128 let mut declarators = Vec::new();
1129 let initializer = if input.eat(&TokenKind::Eq) {
1130 Some(parse_expression(input)?)
1131 } else {
1132 None
1133 };
1134 declarators.push(VariableDeclarator {
1135 name: Some(name),
1136 dims,
1137 initializer,
1138 });
1139 while input.eat(&TokenKind::Comma) {
1140 let name = input.parse_ident()?;
1141 let dims = parse_array_dims(input)?;
1142 let initializer = if input.eat(&TokenKind::Eq) {
1143 Some(parse_expression(input)?)
1144 } else {
1145 None
1146 };
1147 declarators.push(VariableDeclarator {
1148 name: Some(name),
1149 dims,
1150 initializer,
1151 });
1152 }
1153 input.expect(TokenKind::Semicolon)?;
1154 let semi_span = input.peek().span;
1155 Ok(InterfaceMemberDecl::Field(FieldDecl {
1156 doc_comment,
1157 modifiers,
1158 ty,
1159 declarators,
1160 semi_span,
1161 }))
1162 }
1163 } else {
1164 Err(crate::error::Error::new(
1165 input.peek().span,
1166 "expected interface member",
1167 ))
1168 }
1169}
1170
1171fn parse_enum_decl(
1176 input: &ParseStream,
1177 doc_comment: Vec<Comment>,
1178 modifiers: Vec<Modifier>,
1179) -> Result<EnumDecl> {
1180 let enum_span = input.peek().span;
1181 input.expect(TokenKind::Enum)?;
1182 let name = input.parse_ident()?;
1183 let implements_clause = parse_implements_clause(input);
1184
1185 input.expect(TokenKind::LBrace)?;
1186 let open = input.peek().span;
1187 let mut constants = Vec::new();
1188 let mut comma_span = None;
1189
1190 while !input.is(&TokenKind::RBrace) && !input.is(&TokenKind::Semicolon) && !input.is_empty() {
1191 let annotations = parse_annotations(input)?;
1192 let name = input.parse_ident()?;
1193 let (paren_span, args) = if input.is(&TokenKind::LParen) {
1194 let open_p = input.peek().span;
1195 input.next();
1196 let args = input.parse_terminated(parse_expression)?;
1197 input.expect(TokenKind::RParen)?;
1198 let close_p = input.peek().span;
1199 (Some((open_p, close_p)), args)
1200 } else {
1201 (None, Vec::new())
1202 };
1203 let body = if input.is(&TokenKind::LBrace) {
1204 Some(parse_class_body_decl_list(input)?)
1205 } else {
1206 None
1207 };
1208 constants.push(EnumConstant {
1209 annotations,
1210 name,
1211 paren_span,
1212 args,
1213 body,
1214 });
1215 if input.eat(&TokenKind::Comma) {
1216 comma_span = Some(input.peek().span);
1217 } else {
1218 break;
1219 }
1220 }
1221
1222 let members = if input.eat(&TokenKind::Semicolon) {
1223 let mut members = Vec::new();
1224 while !input.is_empty() {
1225 if input.is(&TokenKind::RBrace) {
1226 break;
1227 }
1228 if input.is(&TokenKind::Semicolon) {
1229 let sp = input.next().span;
1230 members.push(ClassBodyDecl::Empty(sp));
1231 continue;
1232 }
1233 members.push(parse_class_body_decl(input)?);
1234 }
1235 members
1236 } else {
1237 Vec::new()
1238 };
1239
1240 input.expect(TokenKind::RBrace)?;
1241 let close = input.peek().span;
1242
1243 Ok(EnumDecl {
1244 doc_comment,
1245 modifiers,
1246 enum_span,
1247 name,
1248 implements_clause,
1249 body: EnumBody {
1250 brace_span: (open, close),
1251 constants,
1252 comma_span,
1253 members,
1254 },
1255 })
1256}
1257
1258fn parse_record_decl(
1263 input: &ParseStream,
1264 doc_comment: Vec<Comment>,
1265 modifiers: Vec<Modifier>,
1266) -> Result<RecordDecl> {
1267 let record_span = input.peek().span;
1268 input.expect(TokenKind::Record)?;
1269 let name = input.parse_ident()?;
1270 let type_params = parse_optional_type_params(input);
1271
1272 input.expect(TokenKind::LParen)?;
1274 let open_p = input.peek().span;
1275 let mut components = Vec::new();
1276 while !input.is(&TokenKind::RParen) && !input.is_empty() {
1277 let annotations = parse_annotations(input)?;
1278 let ty = parse_type(input)?;
1279 let name = input.parse_ident()?;
1280 if input.eat(&TokenKind::Ellipsis) {
1281 let ellipsis_span = input.peek().span;
1282 components.push(RecordComponent::VarArgs {
1283 annotations,
1284 ty,
1285 ellipsis_span,
1286 name,
1287 });
1288 } else {
1289 components.push(RecordComponent::Normal {
1290 annotations,
1291 ty,
1292 name,
1293 });
1294 }
1295 if !input.eat(&TokenKind::Comma) {
1296 break;
1297 }
1298 }
1299 input.expect(TokenKind::RParen)?;
1300 let close_p = input.peek().span;
1301
1302 let implements_clause = parse_implements_clause(input);
1303
1304 input.expect(TokenKind::LBrace)?;
1306 let open = input.peek().span;
1307 let mut members = Vec::new();
1308 while !input.is_empty() {
1309 if input.is(&TokenKind::RBrace) {
1310 break;
1311 }
1312 if input.is(&TokenKind::Semicolon) {
1313 let sp = input.next().span;
1314 members.push(RecordBodyDecl::Empty(sp));
1315 continue;
1316 }
1317 members.push(parse_record_body_decl(input)?);
1318 }
1319 input.expect(TokenKind::RBrace)?;
1320 let close = input.peek().span;
1321
1322 Ok(RecordDecl {
1323 doc_comment,
1324 modifiers,
1325 record_span,
1326 name,
1327 type_params,
1328 components: RecordComponents {
1329 paren_span: (open_p, close_p),
1330 components,
1331 },
1332 implements_clause,
1333 body: RecordBody {
1334 brace_span: (open, close),
1335 members,
1336 },
1337 })
1338}
1339
1340fn parse_record_body_decl(input: &ParseStream) -> Result<RecordBodyDecl> {
1341 let doc_comment = input.collect_pending_doc_comments();
1342 let modifiers = parse_modifiers(input);
1343
1344 if input.is_any_ident() && input.look_ahead(1).kind == TokenKind::LBrace {
1348 let name = input.parse_ident()?;
1349 let body = parse_constructor_body(input)?;
1350 return Ok(RecordBodyDecl::CompactConstructor(CompactConstructorDecl {
1351 doc_comment,
1352 modifiers,
1353 name,
1354 body,
1355 }));
1356 }
1357
1358 match &input.peek().kind {
1359 TokenKind::LBrace => {
1360 let block = parse_block(input, Vec::new())?;
1361 Ok(RecordBodyDecl::InstanceInit(InstanceInit { block }))
1362 }
1363 TokenKind::Static => {
1364 let static_span = input.peek().span;
1365 input.next();
1366 if input.is(&TokenKind::LBrace) {
1367 let block = parse_block(input, Vec::new())?;
1368 Ok(RecordBodyDecl::StaticInit(StaticInit {
1369 static_span,
1370 block,
1371 }))
1372 } else {
1373 let mut rest_mods = modifiers;
1374 rest_mods.push(Modifier::Static(static_span));
1375 let rest = parse_modifiers(input);
1376 rest_mods.extend(rest);
1377 parse_record_body_decl_with_mods(input, doc_comment, rest_mods)
1379 }
1380 }
1381 TokenKind::Class => {
1382 let decl = parse_class_decl(input, doc_comment, modifiers)?;
1383 Ok(RecordBodyDecl::Class(decl))
1384 }
1385 TokenKind::Interface => {
1386 let decl = parse_interface_decl(input, doc_comment, modifiers)?;
1387 Ok(RecordBodyDecl::Interface(decl))
1388 }
1389 TokenKind::Enum => {
1390 let decl = parse_enum_decl(input, doc_comment, modifiers)?;
1391 Ok(RecordBodyDecl::Enum(decl))
1392 }
1393 TokenKind::Record => {
1394 let decl = parse_record_decl(input, doc_comment, modifiers)?;
1395 Ok(RecordBodyDecl::Record(decl))
1396 }
1397 _ => parse_record_body_decl_with_mods(input, doc_comment, modifiers),
1398 }
1399}
1400
1401fn parse_record_body_decl_with_mods(
1402 input: &ParseStream,
1403 doc_comment: Vec<Comment>,
1404 modifiers: Vec<Modifier>,
1405) -> Result<RecordBodyDecl> {
1406 let type_params = parse_optional_type_params(input);
1407 let ty = parse_type(input)?;
1408 if input.is_any_ident() {
1409 let name = input.parse_ident()?;
1410 if input.is(&TokenKind::LParen) {
1411 input.expect(TokenKind::LParen)?;
1412 let open = input.peek().span;
1413 let params = parse_formal_params_after_lparen(input)?;
1414 let throws_clause = parse_throws_clause(input)?;
1415 let body = if input.is(&TokenKind::LBrace) {
1416 Some(parse_block(input, Vec::new())?)
1417 } else {
1418 input.expect(TokenKind::Semicolon)?;
1419 None
1420 };
1421 return Ok(RecordBodyDecl::Method(MethodDecl {
1422 doc_comment,
1423 modifiers,
1424 type_params,
1425 return_type: ty.into(),
1426 name,
1427 receiver_param: None,
1428 params,
1429 paren_span: (open, input.peek().span),
1430 throws_clause,
1431 body,
1432 }));
1433 }
1434 let mut declarators = Vec::new();
1435 let dims = parse_array_dims(input)?;
1436 let initializer = if input.eat(&TokenKind::Eq) {
1437 Some(parse_expression(input)?)
1438 } else {
1439 None
1440 };
1441 declarators.push(VariableDeclarator {
1442 name: Some(name),
1443 dims,
1444 initializer,
1445 });
1446 while input.eat(&TokenKind::Comma) {
1447 let name = input.parse_ident()?;
1448 let dims = parse_array_dims(input)?;
1449 let initializer = if input.eat(&TokenKind::Eq) {
1450 Some(parse_expression(input)?)
1451 } else {
1452 None
1453 };
1454 declarators.push(VariableDeclarator {
1455 name: Some(name),
1456 dims,
1457 initializer,
1458 });
1459 }
1460 input.expect(TokenKind::Semicolon)?;
1461 let semi_span = input.peek().span;
1462 Ok(RecordBodyDecl::Field(FieldDecl {
1463 doc_comment,
1464 modifiers,
1465 ty,
1466 declarators,
1467 semi_span,
1468 }))
1469 } else if input.is(&TokenKind::LParen) {
1470 let name = extract_constructor_name_from_type(&ty)?;
1473 input.expect(TokenKind::LParen)?;
1474 let open = input.peek().span;
1475 let params = parse_formal_params_after_lparen(input)?;
1476 let throws_clause = parse_throws_clause(input)?;
1477 let body = parse_constructor_body(input)?;
1478 Ok(RecordBodyDecl::Constructor(ConstructorDecl {
1479 doc_comment,
1480 modifiers,
1481 type_params,
1482 name,
1483 receiver_param: None,
1484 params,
1485 paren_span: (open, input.peek().span),
1486 throws_clause,
1487 body,
1488 }))
1489 } else {
1490 Err(crate::error::Error::new(
1491 input.peek().span,
1492 "expected record body member",
1493 ))
1494 }
1495}
1496
1497fn extract_constructor_name_from_type(ty: &Type) -> Result<Ident> {
1500 match ty {
1501 Type::Reference(ReferenceType::ClassOrInterfaceType(cty)) => {
1502 if cty.path.segments.len() == 1 && cty.path.segments[0].args.is_none() {
1503 Ok(cty.path.segments[0].ident.clone())
1504 } else {
1505 Err(crate::error::Error::new(
1506 cty.path.span,
1507 "expected simple identifier for constructor name",
1508 ))
1509 }
1510 }
1511 _ => Err(crate::error::Error::new(
1512 ty.span(),
1513 "expected simple identifier for constructor name",
1514 )),
1515 }
1516}
1517
1518fn parse_constructor_body(input: &ParseStream) -> Result<ConstructorBody> {
1519 input.expect(TokenKind::LBrace)?;
1520 let open = input.peek().span;
1521 let mut explicit_constructor_call = None;
1522 let mut stmts = Vec::new();
1523
1524 if input.is(&TokenKind::This) || input.is(&TokenKind::Super) {
1525 let saved = input.cursor();
1526 let call = input.try_parse(parse_explicit_constructor_call);
1527 if let Some(call) = call {
1528 explicit_constructor_call = Some(call);
1529 } else {
1530 input.set_cursor(saved);
1531 }
1532 }
1533
1534 while !input.is_empty() {
1535 if input.is(&TokenKind::RBrace) {
1536 break;
1537 }
1538 stmts.push(parse_statement(input)?);
1539 }
1540 input.expect(TokenKind::RBrace)?;
1541 let close = input.peek().span;
1542 Ok(ConstructorBody {
1543 brace_span: (open, close),
1544 explicit_constructor_call,
1545 stmts,
1546 })
1547}
1548
1549fn parse_explicit_constructor_call(input: &ParseStream) -> Result<ExplicitConstructorCall> {
1550 let type_args = parse_optional_type_arguments(input);
1551 match &input.peek().kind {
1552 TokenKind::This => {
1553 let this_span = input.peek().span;
1554 input.next();
1555 input.expect(TokenKind::LParen)?;
1556 let open = input.peek().span;
1557 let args = input.parse_terminated(parse_expression)?;
1558 input.expect(TokenKind::RParen)?;
1559 let close = input.peek().span;
1560 input.expect(TokenKind::Semicolon)?;
1561 let semi_span = input.peek().span;
1562 Ok(ExplicitConstructorCall::This {
1563 type_args,
1564 this_span,
1565 paren_span: (open, close),
1566 args,
1567 semi_span,
1568 })
1569 }
1570 TokenKind::Super => {
1571 let super_span = input.peek().span;
1572 input.next();
1573 input.expect(TokenKind::LParen)?;
1574 let open = input.peek().span;
1575 let args = input.parse_terminated(parse_expression)?;
1576 input.expect(TokenKind::RParen)?;
1577 let close = input.peek().span;
1578 input.expect(TokenKind::Semicolon)?;
1579 let semi_span = input.peek().span;
1580 Ok(ExplicitConstructorCall::Super {
1581 type_args,
1582 super_span,
1583 paren_span: (open, close),
1584 args,
1585 semi_span,
1586 })
1587 }
1588 _ => Err(crate::error::Error::new(
1589 input.peek().span,
1590 "expected this or super",
1591 )),
1592 }
1593}
1594
1595fn parse_annotation_path(input: &ParseStream) -> Result<Path> {
1601 let start = input.peek().span;
1602 let ident = input.parse_ident()?;
1603 let mut segments = vec![PathSegment { ident, args: None }];
1604
1605 while input.is(&TokenKind::Dot) {
1606 let saved = input.cursor();
1607 input.next();
1608 if input.is_any_ident() || is_contextual_type_keyword(&input.peek().kind) {
1609 let ident = input.parse_ident()?;
1610 segments.push(PathSegment { ident, args: None });
1611 } else {
1612 input.set_cursor(saved);
1613 break;
1614 }
1615 }
1616
1617 let end = if input.cursor() > 0 {
1618 input.look_ahead(0).span
1619 } else {
1620 start
1621 };
1622
1623 Ok(Path {
1624 segments,
1625 span: start.join(end),
1626 })
1627}
1628
1629fn parse_path(input: &ParseStream) -> Result<Path> {
1630 let start = input.peek().span;
1631 let ident = input.parse_ident()?;
1632 let args = parse_optional_type_arguments(input);
1633 let mut segments = vec![PathSegment { ident, args }];
1634
1635 while input.is(&TokenKind::Dot) {
1636 let saved = input.cursor();
1638 input.next(); let _annotations = parse_type_annotations(input);
1641 if input.is_any_ident() || is_contextual_type_keyword(&input.peek().kind) {
1642 let ident = input.parse_ident()?;
1643 let args = parse_optional_type_arguments(input);
1644 segments.push(PathSegment { ident, args });
1645 } else {
1646 input.set_cursor(saved);
1647 break;
1648 }
1649 }
1650
1651 let end = if input.cursor() > 0 {
1652 input.look_ahead(0).span
1653 } else {
1654 start
1655 };
1656 Ok(Path {
1657 segments,
1658 span: start.join(end),
1659 })
1660}
1661
1662fn is_contextual_type_keyword(kind: &TokenKind) -> bool {
1663 matches!(
1664 kind,
1665 TokenKind::Record | TokenKind::Sealed | TokenKind::Var | TokenKind::Yield | TokenKind::Open
1666 )
1667}
1668
1669fn parse_type(input: &ParseStream) -> Result<Type> {
1674 let annotations = parse_type_annotations(input);
1675 let start = if let Some(ann) = annotations.first() {
1676 ann.span()
1677 } else {
1678 input.peek().span
1679 };
1680
1681 if input.is(&TokenKind::Void) {
1682 input.next();
1683 return Ok(Type::Void(input.peek().span));
1684 }
1685
1686 let base = if is_primitive_type_token(&input.peek().kind) {
1687 let prim = parse_primitive_type(input)?;
1688 Type::Primitive(prim)
1689 } else if input.is_any_ident() || is_contextual_type_keyword(&input.peek().kind) {
1690 let path = parse_path(input)?;
1691 Type::Reference(ReferenceType::ClassOrInterfaceType(ClassOrInterfaceType {
1692 path,
1693 annotations_prefix: annotations,
1694 }))
1695 } else {
1696 return Err(crate::error::Error::new(input.peek().span, "expected type"));
1697 };
1698
1699 let dims = parse_array_dims(input)?;
1700 if dims.is_empty() {
1701 Ok(base)
1702 } else {
1703 let span = start.join(dims.last().unwrap().bracket_span.1);
1704 Ok(Type::Reference(ReferenceType::Array(ArrayType {
1705 elem_type: Box::new(base),
1706 dims,
1707 span,
1708 })))
1709 }
1710}
1711
1712fn parse_type_annotations(input: &ParseStream) -> Vec<Annotation> {
1713 let mut anns = Vec::new();
1714 while input.is(&TokenKind::At) {
1715 let saved = input.cursor();
1717 input.next(); if input.is(&TokenKind::Interface) {
1719 input.set_cursor(saved);
1720 break;
1721 }
1722 input.set_cursor(saved);
1723 if let Some(ann) = input.try_parse(|i| i.parse::<Annotation>()) {
1724 anns.push(ann);
1725 } else {
1726 break;
1727 }
1728 }
1729 anns
1730}
1731
1732fn parse_annotation_type_body(input: &ParseStream) -> Result<AnnotationInterfaceBody> {
1733 input.expect(TokenKind::LBrace)?;
1734 let open = input.peek().span;
1735 let mut members = Vec::new();
1736 while !input.is_empty() {
1737 if input.is(&TokenKind::RBrace) {
1738 break;
1739 }
1740 if input.eat(&TokenKind::Semicolon) {
1741 members.push(AnnotationInterfaceMember::Empty(input.peek().span));
1742 continue;
1743 }
1744 let doc_comment = input.collect_pending_doc_comments();
1745 let modifiers = parse_modifiers(input);
1746 let annotations = parse_annotations(input)?;
1747 let mut all_mods: Vec<Modifier> = annotations
1748 .iter()
1749 .map(|a| Modifier::Annotation(a.clone()))
1750 .collect();
1751 all_mods.extend(modifiers);
1752
1753 if input.is(&TokenKind::At) {
1754 let saved = input.cursor();
1756 let at_span = input.peek().span;
1757 input.next();
1758 if input.is(&TokenKind::Interface) {
1759 input.next();
1760 let name = input.parse_ident()?;
1761 let body = parse_annotation_type_body(input)?;
1762 members.push(AnnotationInterfaceMember::AnnotationInterface(
1763 AnnotationInterfaceDecl {
1764 doc_comment,
1765 modifiers: all_mods,
1766 at_span,
1767 interface_span: name.span(),
1768 name,
1769 body,
1770 },
1771 ));
1772 continue;
1773 }
1774 input.set_cursor(saved);
1775 }
1776
1777 if input.is(&TokenKind::Class) {
1779 let decl = parse_class_decl(input, doc_comment, all_mods)?;
1780 members.push(AnnotationInterfaceMember::Class(decl));
1781 continue;
1782 }
1783 if input.is(&TokenKind::Interface) {
1784 let decl = parse_interface_decl(input, doc_comment, all_mods)?;
1785 members.push(AnnotationInterfaceMember::Interface(decl));
1786 continue;
1787 }
1788 if input.is(&TokenKind::Enum) {
1789 let decl = parse_enum_decl(input, doc_comment, all_mods)?;
1790 members.push(AnnotationInterfaceMember::Enum(decl));
1791 continue;
1792 }
1793 if input.is(&TokenKind::Record) {
1794 let decl: RecordDecl = parse_record_decl(input, doc_comment, all_mods)?;
1795 members.push(AnnotationInterfaceMember::Record(decl));
1796 continue;
1797 }
1798 let ty = parse_type(input)?;
1800 let dims = parse_array_dims(input)?;
1801 let name = input.parse_ident()?;
1802
1803 if input.is(&TokenKind::LParen) {
1804 let open_paren = input.peek().span;
1806 input.next();
1807 input.expect(TokenKind::RParen)?;
1808 let close_paren = input.peek().span;
1809 let default_value = if input.eat(&TokenKind::Default) {
1810 let eq_span = input.peek().span;
1811 let val = parse_element_value(input)?;
1812 Some((eq_span, val))
1813 } else {
1814 None
1815 };
1816 input.expect(TokenKind::Semicolon)?;
1817 let semi_span = input.peek().span;
1818 members.push(AnnotationInterfaceMember::Element(AnnotationElement {
1819 modifiers: all_mods,
1820 ty,
1821 name,
1822 paren_span: (open_paren, close_paren),
1823 dims,
1824 default_value,
1825 semi_span,
1826 }));
1827 } else {
1828 let mut declarators = Vec::new();
1830 let initializer = if input.eat(&TokenKind::Eq) {
1831 Some(parse_expression(input)?)
1832 } else {
1833 None
1834 };
1835 declarators.push(VariableDeclarator {
1836 name: Some(name),
1837 dims,
1838 initializer,
1839 });
1840 while input.eat(&TokenKind::Comma) {
1841 let name = input.parse_ident()?;
1842 let dims = parse_array_dims(input)?;
1843 let initializer = if input.eat(&TokenKind::Eq) {
1844 Some(parse_expression(input)?)
1845 } else {
1846 None
1847 };
1848 declarators.push(VariableDeclarator {
1849 name: Some(name),
1850 dims,
1851 initializer,
1852 });
1853 }
1854 input.expect(TokenKind::Semicolon)?;
1855 let semi_span = input.peek().span;
1856 members.push(AnnotationInterfaceMember::Field(FieldDecl {
1857 doc_comment,
1858 modifiers: all_mods,
1859 ty,
1860 declarators,
1861 semi_span,
1862 }));
1863 }
1864 }
1865 input.expect(TokenKind::RBrace)?;
1866 let close = input.peek().span;
1867 Ok(AnnotationInterfaceBody {
1868 brace_span: (open, close),
1869 members,
1870 })
1871}
1872
1873fn is_primitive_type_token(kind: &TokenKind) -> bool {
1874 matches!(
1875 kind,
1876 TokenKind::Byte
1877 | TokenKind::Short
1878 | TokenKind::Int
1879 | TokenKind::Long
1880 | TokenKind::Char
1881 | TokenKind::Float
1882 | TokenKind::Double
1883 | TokenKind::Boolean
1884 )
1885}
1886
1887fn parse_primitive_type(input: &ParseStream) -> Result<PrimitiveType> {
1888 let prim = match &input.peek().kind {
1889 TokenKind::Byte => PrimitiveType::Byte,
1890 TokenKind::Short => PrimitiveType::Short,
1891 TokenKind::Int => PrimitiveType::Int,
1892 TokenKind::Long => PrimitiveType::Long,
1893 TokenKind::Char => PrimitiveType::Char,
1894 TokenKind::Float => PrimitiveType::Float,
1895 TokenKind::Double => PrimitiveType::Double,
1896 TokenKind::Boolean => PrimitiveType::Boolean,
1897 _ => {
1898 return Err(crate::error::Error::new(
1899 input.peek().span,
1900 "expected primitive type",
1901 ));
1902 }
1903 };
1904 input.next();
1905 Ok(prim)
1906}
1907fn parse_array_dims(input: &ParseStream) -> Result<Vec<ArrayDim>> {
1908 let mut dims = Vec::new();
1909 loop {
1910 let saved = input.cursor();
1913 let _pre_annotations = parse_type_annotations(input);
1914 if !input.is(&TokenKind::LBracket) {
1915 input.set_cursor(saved);
1917 break;
1918 }
1919 let open = input.peek().span;
1920 input.next();
1921 let annotations = parse_type_annotations(input);
1922 input.expect(TokenKind::RBracket)?;
1923 let close = input.peek().span;
1924 dims.push(ArrayDim {
1925 bracket_span: (open, close),
1926 annotations,
1927 });
1928 }
1929 Ok(dims)
1930}
1931fn parse_type_list(input: &ParseStream) -> Vec<Type> {
1932 let mut types = Vec::new();
1933 while let Ok(ty) = parse_type(input) {
1934 types.push(ty);
1935 if !input.eat(&TokenKind::Comma) {
1936 break;
1937 }
1938 }
1939 types
1940}
1941fn parse_optional_type_params(input: &ParseStream) -> Option<TypeParameters> {
1945 if input.is(&TokenKind::Lt) {
1946 parse_type_params(input).ok()
1947 } else {
1948 None
1949 }
1950}
1951
1952fn parse_type_params(input: &ParseStream) -> Result<TypeParameters> {
1953 let lt_span = input.peek().span;
1954 input.expect(TokenKind::Lt)?;
1955 let mut gt_spans = Vec::new();
1956 let mut params = Vec::new();
1957 loop {
1958 let annotations = parse_annotations(input)?;
1959 let name = input.parse_ident()?;
1960 let bound = if input.eat(&TokenKind::Extends) {
1961 let extends_span = input.peek().span;
1962 let _annotations = parse_type_annotations(input);
1964 let first = parse_path(input)?;
1965 let mut additional = Vec::new();
1966 while input.eat(&TokenKind::Amp) {
1967 let _annotations = parse_type_annotations(input);
1968 additional.push(parse_path(input)?);
1969 }
1970 Some(TypeBound {
1971 first,
1972 additional,
1973 extends_span,
1974 })
1975 } else {
1976 None
1977 };
1978 let span = annotations
1979 .first()
1980 .map(|a| a.span())
1981 .unwrap_or(name.span())
1982 .join(
1983 bound
1984 .as_ref()
1985 .map(|b| {
1986 b.additional
1987 .last()
1988 .map(|p| p.span)
1989 .unwrap_or_else(|| b.first.span)
1990 })
1991 .unwrap_or(name.span()),
1992 );
1993 params.push(TypeParameter {
1994 annotations,
1995 name,
1996 bound,
1997 span,
1998 });
1999 if input.eat(&TokenKind::Gt) {
2000 gt_spans.push(input.peek().span);
2001 break;
2002 }
2003 if input.is(&TokenKind::GtGt) {
2004 input.split_gt();
2006 gt_spans.push(input.peek().span);
2007 break;
2008 }
2009 if input.is(&TokenKind::GtGtGt) {
2010 input.split_gt();
2012 gt_spans.push(input.peek().span);
2013 break;
2014 }
2015 input.expect(TokenKind::Comma)?;
2016 }
2017 Ok(TypeParameters {
2018 params,
2019 lt_span,
2020 gt_spans,
2021 })
2022}
2023
2024fn parse_optional_type_arguments(input: &ParseStream) -> Option<TypeArguments> {
2025 if input.is(&TokenKind::Lt) {
2026 parse_type_arguments(input).ok()
2027 } else {
2028 None
2029 }
2030}
2031
2032fn parse_type_arguments(input: &ParseStream) -> Result<TypeArguments> {
2033 let lt_span = input.peek().span;
2034 input.expect(TokenKind::Lt)?;
2035 if input.eat(&TokenKind::Gt) {
2037 let gt_spans = vec![input.peek().span];
2038 return Ok(TypeArguments {
2039 args: vec![],
2040 lt_token: lt_span,
2041 gt_tokens: gt_spans,
2042 });
2043 }
2044 let mut gt_spans = Vec::new();
2045 let mut args = Vec::new();
2046 loop {
2047 if input.eat(&TokenKind::Question) {
2048 let wildcard_span = input.peek().span;
2049 let bound = if input.eat(&TokenKind::Extends) {
2050 Some(WildcardBound::Extends(Box::new(parse_type(input)?)))
2051 } else if input.eat(&TokenKind::Super) {
2052 Some(WildcardBound::Super(Box::new(parse_type(input)?)))
2053 } else {
2054 None
2055 };
2056 args.push(TypeArgument::Wildcard(Wildcard {
2057 bound,
2058 span: wildcard_span,
2059 }));
2060 } else {
2061 args.push(TypeArgument::Type(Box::new(parse_type(input)?)));
2062 }
2063 if input.eat(&TokenKind::Gt) {
2064 gt_spans.push(input.peek().span);
2065 break;
2066 }
2067 if input.is(&TokenKind::GtGt) {
2068 input.split_gt();
2070 gt_spans.push(input.peek().span);
2071 break;
2072 }
2073 if input.is(&TokenKind::GtGtGt) {
2074 input.split_gt();
2076 gt_spans.push(input.peek().span);
2077 break;
2078 }
2079 input.expect(TokenKind::Comma)?;
2080 }
2081 Ok(TypeArguments {
2082 args,
2083 lt_token: lt_span,
2084 gt_tokens: gt_spans,
2085 })
2086}
2087
2088fn parse_block(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Block> {
2093 let open = input.peek().span;
2094 input.expect(TokenKind::LBrace)?;
2095 let mut stmts = Vec::new();
2096 while !input.is_empty() {
2097 if input.is(&TokenKind::RBrace) {
2098 break;
2099 }
2100 stmts.push(parse_statement(input)?);
2101 }
2102 input.expect(TokenKind::RBrace)?;
2103 let close = input.peek().span;
2104 Ok(Block {
2105 leading_comments,
2106 brace_span: (open, close),
2107 stmts,
2108 })
2109}
2110
2111fn parse_statement(input: &ParseStream) -> Result<Stmt> {
2112 let leading_comments = input.collect_pending_comments();
2113 parse_statement_with_comments(input, leading_comments)
2114}
2115
2116fn parse_statement_with_comments(
2117 input: &ParseStream,
2118 leading_comments: Vec<Comment>,
2119) -> Result<Stmt> {
2120 if input.is(&TokenKind::LBrace) {
2121 let block = parse_block(input, leading_comments)?;
2122 return Ok(Stmt::Block(block));
2123 }
2124 if input.is(&TokenKind::Semicolon) {
2125 let sp = input.next().span;
2126 return Ok(Stmt::Empty(sp));
2127 }
2128 if input.is(&TokenKind::If) {
2129 return parse_if_stmt(input, leading_comments);
2130 }
2131 if input.is(&TokenKind::Assert) {
2132 return parse_assert_stmt(input, leading_comments);
2133 }
2134 if input.is(&TokenKind::Switch) {
2135 return parse_switch_stmt(input, leading_comments);
2136 }
2137 if input.is(&TokenKind::While) {
2138 return parse_while_stmt(input, leading_comments);
2139 }
2140 if input.is(&TokenKind::Do) {
2141 return parse_do_while_stmt(input, leading_comments);
2142 }
2143 if input.is(&TokenKind::For) {
2144 return parse_for_stmt(input, leading_comments);
2145 }
2146 if input.is(&TokenKind::Break) {
2147 return parse_jump_stmt(input, TokenKind::Break, Stmt::Break, leading_comments);
2148 }
2149 if input.is(&TokenKind::Continue) {
2150 return parse_jump_stmt(input, TokenKind::Continue, Stmt::Continue, leading_comments);
2151 }
2152 if input.is(&TokenKind::Return) {
2153 return parse_return_stmt(input, leading_comments);
2154 }
2155 if input.is(&TokenKind::Throw) {
2156 return parse_throw_stmt(input, leading_comments);
2157 }
2158 if input.is(&TokenKind::Synchronized) {
2159 return parse_synchronized_stmt(input, leading_comments);
2160 }
2161 if input.is(&TokenKind::Try) {
2162 return parse_try_stmt(input, leading_comments);
2163 }
2164 if input.is(&TokenKind::Yield) {
2165 return parse_yield_stmt(input, leading_comments);
2166 }
2167
2168 if input.is_any_ident() {
2170 let saved = input.cursor();
2171 let ident = input.parse_ident().ok();
2172 if let Some(ident) = ident {
2173 if input.is(&TokenKind::Colon) {
2174 let colon_span = input.peek().span;
2175 input.next();
2176 let stmt = parse_statement(input)?;
2177 return Ok(Stmt::Labeled(LabeledStmt {
2178 leading_comments,
2179 label: ident,
2180 colon_span,
2181 stmt: Box::new(stmt),
2182 }));
2183 }
2184 input.set_cursor(saved);
2185 } else {
2186 input.set_cursor(saved);
2187 }
2188 }
2189
2190 if input.is(&TokenKind::Class)
2193 || input.is(&TokenKind::Interface)
2194 || input.is(&TokenKind::Enum)
2195 || input.is(&TokenKind::Record)
2196 || input.is(&TokenKind::At)
2197 || is_modifier_keyword(&input.peek().kind)
2198 {
2199 let saved = input.cursor();
2200 match input.try_parse(|i| {
2201 let _modifiers = parse_modifiers(i);
2204 if !matches!(
2205 i.peek().kind,
2206 TokenKind::Class | TokenKind::Interface | TokenKind::Enum | TokenKind::Record
2207 ) {
2208 return Err(crate::error::Error::new(i.peek().span, "not a local class"));
2209 }
2210 TypeDecl::parse(i)
2211 }) {
2212 Some(decl) => return Ok(Stmt::ClassDecl(Box::new(decl))),
2213 None => {
2214 input.set_cursor(saved);
2215 }
2216 }
2217 }
2218
2219 let saved = input.cursor();
2222 if let Some(stmt) = try_parse_local_var_decl_or_expr_stmt(input, leading_comments.clone()) {
2223 return Ok(stmt);
2224 }
2225 input.set_cursor(saved);
2226
2227 let expr = parse_expression(input)?;
2229 input.expect(TokenKind::Semicolon)?;
2230 let semi_span = input.peek().span;
2231 Ok(Stmt::Expr(ExprStmt {
2232 leading_comments,
2233 expr,
2234 semi_span,
2235 }))
2236}
2237
2238fn try_parse_local_var_decl_or_expr_stmt(
2239 input: &ParseStream,
2240 leading_comments: Vec<Comment>,
2241) -> Option<Stmt> {
2242 let modifiers = parse_modifiers(input);
2243 let is_var = input.is(&TokenKind::Var);
2244 let can_start_type = crate::token::can_start_type(&input.peek().kind);
2245
2246 if is_var || can_start_type {
2247 let saved = input.cursor();
2248 let ty_result = if is_var {
2249 let var_span = input.peek().span;
2250 input.next();
2251 Ok(LocalVarType::Var(var_span))
2252 } else {
2253 parse_type(input).map(LocalVarType::Type)
2254 };
2255
2256 if let Ok(ty) = ty_result {
2257 if input.is_any_ident() {
2259 let name = input.parse_ident().ok()?;
2260 let dims = parse_array_dims(input).ok().unwrap_or_default();
2261 let initializer = if input.eat(&TokenKind::Eq) {
2262 parse_expression(input).ok()
2263 } else {
2264 None
2265 };
2266 let mut declarators = vec![VariableDeclarator {
2267 name: Some(name),
2268 dims,
2269 initializer,
2270 }];
2271 while input.eat(&TokenKind::Comma) {
2272 let name = input.parse_ident().ok()?;
2273 let dims = parse_array_dims(input).ok().unwrap_or_default();
2274 let init = if input.eat(&TokenKind::Eq) {
2275 parse_expression(input).ok()
2276 } else {
2277 None
2278 };
2279 declarators.push(VariableDeclarator {
2280 name: Some(name),
2281 dims,
2282 initializer: init,
2283 });
2284 }
2285 if input.eat(&TokenKind::Semicolon) {
2286 let semi_span = input.peek().span;
2287 return Some(Stmt::LocalVarDecl(LocalVarDeclStmt {
2288 leading_comments,
2289 modifiers,
2290 ty,
2291 declarators,
2292 semi_span,
2293 }));
2294 }
2295 }
2296 }
2297 input.set_cursor(saved);
2298 }
2299 None
2300}
2301
2302fn parse_if_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2303 let if_span = input.peek().span;
2304 input.expect(TokenKind::If)?;
2305 input.expect(TokenKind::LParen)?;
2306 let open = input.peek().span;
2307 let cond = parse_expression(input)?;
2308 input.expect(TokenKind::RParen)?;
2309 let close = input.peek().span;
2310 let then_stmt = parse_statement(input)?;
2311 let else_clause = if input.eat(&TokenKind::Else) {
2312 let else_span = input.peek().span;
2313 let else_stmt = parse_statement(input)?;
2314 Some((else_span, Box::new(else_stmt)))
2315 } else {
2316 None
2317 };
2318 Ok(Stmt::If(IfStmt {
2319 leading_comments,
2320 if_span,
2321 paren_span: (open, close),
2322 cond,
2323 then_stmt: Box::new(then_stmt),
2324 else_clause,
2325 }))
2326}
2327
2328fn parse_assert_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2329 let assert_span = input.peek().span;
2330 input.expect(TokenKind::Assert)?;
2331 let cond = parse_expression(input)?;
2332 let detail = if input.eat(&TokenKind::Colon) {
2333 let colon_span = input.peek().span;
2334 let detail = parse_expression(input)?;
2335 Some((colon_span, detail))
2336 } else {
2337 None
2338 };
2339 input.expect(TokenKind::Semicolon)?;
2340 let semi_span = input.peek().span;
2341 Ok(Stmt::Assert(AssertStmt {
2342 leading_comments,
2343 assert_span,
2344 cond,
2345 detail,
2346 semi_span,
2347 }))
2348}
2349
2350fn parse_switch_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2351 let switch_span = input.peek().span;
2352 input.expect(TokenKind::Switch)?;
2353 input.expect(TokenKind::LParen)?;
2354 let open = input.peek().span;
2355 let selector = parse_expression(input)?;
2356 input.expect(TokenKind::RParen)?;
2357 let close = input.peek().span;
2358 input.expect(TokenKind::LBrace)?;
2359 let brace_open = input.peek().span;
2360 let mut cases = Vec::new();
2361 while !input.is_empty() {
2362 if input.is(&TokenKind::RBrace) {
2363 break;
2364 }
2365 let labels = parse_switch_labels(input)?;
2366 let colon_span = if input.eat(&TokenKind::Colon) || input.eat(&TokenKind::Arrow) {
2367 input.peek().span
2368 } else {
2369 break;
2370 };
2371 let mut stmts = Vec::new();
2372 while !input.is_empty() {
2373 if is_switch_label_start(input) || input.is(&TokenKind::RBrace) {
2374 break;
2375 }
2376 stmts.push(parse_statement(input)?);
2377 }
2378 cases.push(SwitchCaseGroup {
2379 labels,
2380 colon_span,
2381 stmts,
2382 });
2383 }
2384 input.expect(TokenKind::RBrace)?;
2385 let brace_close = input.peek().span;
2386 Ok(Stmt::Switch(SwitchStmt {
2387 leading_comments,
2388 switch_span,
2389 paren_span: (open, close),
2390 selector,
2391 brace_span: (brace_open, brace_close),
2392 cases,
2393 }))
2394}
2395
2396fn is_any_ident_kind(kind: &TokenKind) -> bool {
2397 matches!(
2398 kind,
2399 TokenKind::Ident(_)
2400 | TokenKind::Record
2401 | TokenKind::Sealed
2402 | TokenKind::Var
2403 | TokenKind::Yield
2404 | TokenKind::Open
2405 | TokenKind::Provides
2406 | TokenKind::Requires
2407 | TokenKind::Uses
2408 | TokenKind::With
2409 | TokenKind::When
2410 | TokenKind::To
2411 | TokenKind::Exports
2412 | TokenKind::Opens
2413 | TokenKind::Transitive
2414 | TokenKind::Permits
2415 | TokenKind::NonSealed
2416 | TokenKind::Module
2417 | TokenKind::Byte
2418 | TokenKind::Short
2419 | TokenKind::Int
2420 | TokenKind::Long
2421 | TokenKind::Char
2422 | TokenKind::Float
2423 | TokenKind::Double
2424 | TokenKind::Boolean
2425 | TokenKind::Void
2426 )
2427}
2428
2429fn is_switch_label_start(input: &ParseStream) -> bool {
2430 input.is(&TokenKind::Case) || input.is(&TokenKind::Default)
2431}
2432
2433fn parse_case_value(input: &ParseStream) -> Result<Expr> {
2435 if input.is_any_ident() && input.look_ahead(1).kind == TokenKind::Arrow {
2438 let ident = input.parse_ident()?;
2439 return Ok(Expr::Ident(ident));
2440 }
2441 if input.is(&TokenKind::LParen) {
2446 let mut depth = 1usize;
2447 let mut offset = 1usize;
2448 loop {
2449 let tok = input.look_ahead(offset);
2450 match &tok.kind {
2451 TokenKind::LParen => depth += 1,
2452 TokenKind::RParen => {
2453 depth -= 1;
2454 if depth == 0 {
2455 break;
2456 }
2457 }
2458 TokenKind::Eof => break,
2459 _ => {}
2460 }
2461 offset += 1;
2462 }
2463 let after_rparen = &input.look_ahead(offset + 1).kind;
2465 let after_that = &input.look_ahead(offset + 2).kind;
2466
2467 if is_any_ident_kind(after_rparen) && matches!(after_that, TokenKind::Arrow) {
2468 let open_span = input.peek().span;
2470 input.next(); let saved = input.cursor();
2472 if let Ok(ty) = parse_type(input)
2473 && input.eat(&TokenKind::RParen)
2474 {
2475 let close_span = input.peek().span;
2476 let ident = input.parse_ident()?;
2477 return Ok(Expr::Cast(CastExpr {
2478 paren_span: (open_span, close_span),
2479 target_type: ty,
2480 expr: Box::new(Expr::Ident(ident)),
2481 }));
2482 }
2483 input.set_cursor(saved);
2484 }
2486
2487 if matches!(after_rparen, TokenKind::Arrow) {
2491 let open_span = input.peek().span;
2493 input.next(); let inner = parse_expression(input)?;
2495 input.expect(TokenKind::RParen)?;
2496 let close_span = input.peek().span;
2497 return Ok(Expr::Paren {
2498 paren_span: (open_span, close_span),
2499 expr: Box::new(inner),
2500 });
2501 }
2502 }
2503 parse_expression(input)
2504}
2505
2506fn parse_switch_labels(input: &ParseStream) -> Result<Vec<SwitchCase>> {
2507 let mut labels = Vec::new();
2508 loop {
2509 if input.is(&TokenKind::Case) {
2510 let case_span = input.peek().span;
2511 input.next();
2512 if input.is(&TokenKind::NullLit) {
2513 let null_span = input.peek().span;
2514 input.next();
2515 if input.eat(&TokenKind::Comma) {
2516 if input.is(&TokenKind::Default) {
2518 let default_span = input.peek().span;
2519 input.next();
2520 labels.push(SwitchCase::CaseNullDefault {
2521 case_span,
2522 null_span,
2523 default_span,
2524 });
2525 break;
2526 }
2527 } else {
2528 labels.push(SwitchCase::CaseNull {
2529 case_span,
2530 null_span,
2531 });
2532 break;
2533 }
2534 } else if input.is(&TokenKind::Default) {
2535 let default_span = input.peek().span;
2536 input.next();
2537 labels.push(SwitchCase::Default { default_span });
2538 break;
2539 } else if is_case_pattern(input) {
2540 let pattern = parse_pattern(input)?;
2542 let guard = if input.is(&TokenKind::When) {
2543 let when_span = input.peek().span;
2544 input.next();
2545 let expr = parse_expression(input)?;
2546 Some(Guard { when_span, expr })
2547 } else {
2548 None
2549 };
2550 labels.push(SwitchCase::CasePattern {
2551 case_span,
2552 pattern,
2553 guard: Box::new(guard),
2554 });
2555 break;
2556 } else {
2557 let mut values = Vec::new();
2558 values.push(parse_case_value(input)?);
2559 while input.eat(&TokenKind::Comma) {
2560 if input.is(&TokenKind::Default) {
2561 let default_span = input.peek().span;
2562 input.next();
2563 labels.push(SwitchCase::CaseValues {
2565 case_span,
2566 values: std::mem::take(&mut values),
2567 });
2568 labels.push(SwitchCase::Default { default_span });
2569 break;
2570 }
2571 values.push(parse_case_value(input)?);
2572 }
2573 if !values.is_empty() {
2574 labels.push(SwitchCase::CaseValues { case_span, values });
2575 }
2576 break;
2577 }
2578 } else if input.is(&TokenKind::Default) {
2579 let default_span = input.peek().span;
2580 input.next();
2581 labels.push(SwitchCase::Default { default_span });
2582 break;
2583 } else {
2584 break;
2585 }
2586 }
2587 Ok(labels)
2588}
2589
2590fn is_case_pattern(input: &ParseStream) -> bool {
2594 if !input.is_any_ident() {
2596 return false;
2597 }
2598 let next = input.look_ahead(1);
2599 match &next.kind {
2600 TokenKind::Ident(_) => true,
2602 TokenKind::LParen => true,
2604 _ => false,
2606 }
2607}
2608
2609fn parse_while_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2610 let while_span = input.peek().span;
2611 input.expect(TokenKind::While)?;
2612 input.expect(TokenKind::LParen)?;
2613 let open = input.peek().span;
2614 let cond = parse_expression(input)?;
2615 input.expect(TokenKind::RParen)?;
2616 let close = input.peek().span;
2617 let body = parse_statement(input)?;
2618 Ok(Stmt::While(WhileStmt {
2619 leading_comments,
2620 while_span,
2621 paren_span: (open, close),
2622 cond,
2623 body: Box::new(body),
2624 }))
2625}
2626
2627fn parse_do_while_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2628 let do_span = input.peek().span;
2629 input.expect(TokenKind::Do)?;
2630 let body = parse_statement(input)?;
2631 let while_span = input.peek().span;
2632 input.expect(TokenKind::While)?;
2633 input.expect(TokenKind::LParen)?;
2634 let open = input.peek().span;
2635 let cond = parse_expression(input)?;
2636 input.expect(TokenKind::RParen)?;
2637 let close = input.peek().span;
2638 input.expect(TokenKind::Semicolon)?;
2639 let semi_span = input.peek().span;
2640 Ok(Stmt::DoWhile(DoWhileStmt {
2641 leading_comments,
2642 do_span,
2643 body: Box::new(body),
2644 while_span,
2645 paren_span: (open, close),
2646 cond,
2647 semi_span,
2648 }))
2649}
2650
2651fn parse_for_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2652 let for_span = input.peek().span;
2653 input.expect(TokenKind::For)?;
2654 input.expect(TokenKind::LParen)?;
2655 let open = input.peek().span;
2656
2657 let saved = input.cursor();
2660
2661 if let Some(stmt) = try_parse_enhanced_for(for_span, open, input, leading_comments.clone()) {
2663 return Ok(stmt);
2664 }
2665 input.set_cursor(saved);
2666
2667 let init = if input.is(&TokenKind::Semicolon) {
2669 input.next();
2670 ForInit::Exprs(Vec::new())
2671 } else {
2672 let inner_saved = input.cursor();
2674 if let Some(var_decl) = try_parse_local_var_decl(input) {
2675 ForInit::LocalVarDecl(var_decl)
2676 } else {
2677 input.set_cursor(inner_saved);
2678 let mut exprs = Vec::new();
2679 exprs.push(parse_expression(input)?);
2680 while input.eat(&TokenKind::Comma) {
2681 exprs.push(parse_expression(input)?);
2682 }
2683 input.expect(TokenKind::Semicolon)?;
2684 ForInit::Exprs(exprs)
2685 }
2686 };
2687
2688 let cond = if input.is(&TokenKind::Semicolon) {
2689 input.next();
2690 None
2691 } else {
2692 let semi1 = Some(input.peek().span);
2693 let cond = parse_expression(input)?;
2694 input.expect(TokenKind::Semicolon)?;
2695 let _ = semi1;
2696 Some(cond)
2697 };
2698
2699 let mut update = Vec::new();
2700 while !input.is(&TokenKind::RParen) && !input.is_empty() {
2701 update.push(parse_expression(input)?);
2702 input.eat(&TokenKind::Comma);
2703 }
2704 input.expect(TokenKind::RParen)?;
2705 let close = input.peek().span;
2706 let body = parse_statement(input)?;
2707
2708 Ok(Stmt::For(ForStmt {
2709 leading_comments,
2710 for_span,
2711 paren_span: (open, close),
2712 init,
2713 cond,
2714 semi2_span: None,
2715 update,
2716 body: Box::new(body),
2717 }))
2718}
2719
2720fn try_parse_local_var_decl(input: &ParseStream) -> Option<LocalVarDeclStmt> {
2721 let modifiers = parse_modifiers(input);
2722 let is_var = input.is(&TokenKind::Var);
2723 let can_start = crate::token::can_start_type(&input.peek().kind);
2724
2725 if is_var || can_start {
2726 let saved = input.cursor();
2727 let ty_result = if is_var {
2728 let var_span = input.peek().span;
2729 input.next();
2730 Ok(LocalVarType::Var(var_span))
2731 } else {
2732 parse_type(input).map(LocalVarType::Type)
2733 };
2734
2735 if let Ok(ty) = ty_result
2736 && input.is_any_ident()
2737 {
2738 let name = input.parse_ident().ok()?;
2739 let dims = parse_array_dims(input).ok().unwrap_or_default();
2740 let initializer = if input.eat(&TokenKind::Eq) {
2741 parse_expression(input).ok()
2742 } else {
2743 None
2744 };
2745 let mut declarators = vec![VariableDeclarator {
2746 name: Some(name),
2747 dims,
2748 initializer,
2749 }];
2750 while input.eat(&TokenKind::Comma) {
2751 let name = input.parse_ident().ok()?;
2752 let dims = parse_array_dims(input).ok().unwrap_or_default();
2753 let init = if input.eat(&TokenKind::Eq) {
2754 parse_expression(input).ok()
2755 } else {
2756 None
2757 };
2758 declarators.push(VariableDeclarator {
2759 name: Some(name),
2760 dims,
2761 initializer: init,
2762 });
2763 }
2764 if input.eat(&TokenKind::Semicolon) {
2765 let semi_span = input.peek().span;
2766 return Some(LocalVarDeclStmt {
2767 leading_comments: Vec::new(),
2768 modifiers,
2769 ty,
2770 declarators,
2771 semi_span,
2772 });
2773 }
2774 }
2775 input.set_cursor(saved);
2776 }
2777 None
2778}
2779
2780fn try_parse_enhanced_for(
2781 for_span: Span,
2782 open: Span,
2783 input: &ParseStream,
2784 leading_comments: Vec<Comment>,
2785) -> Option<Stmt> {
2786 let modifiers = parse_modifiers(input);
2787 let is_var = input.is(&TokenKind::Var);
2788 let can_start = crate::token::can_start_type(&input.peek().kind);
2789
2790 if !is_var && !can_start {
2791 input.set_cursor(input.cursor()); return None;
2793 }
2794
2795 let saved = input.cursor();
2796 let ty_result = if is_var {
2797 let var_span = input.peek().span;
2798 input.next();
2799 Ok(LocalVarType::Var(var_span))
2800 } else {
2801 parse_type(input).map(LocalVarType::Type)
2802 };
2803
2804 if let Ok(ty) = ty_result
2805 && input.is_any_ident()
2806 {
2807 let name = input.parse_ident().ok()?;
2808 let dims = parse_array_dims(input).ok().unwrap_or_default();
2809 if input.eat(&TokenKind::Colon) {
2810 let colon_span = input.peek().span;
2811 let iterable = parse_expression(input).ok()?;
2812 input.expect(TokenKind::RParen).ok()?;
2813 let close = input.peek().span;
2814 let body = parse_statement(input).ok()?;
2815 return Some(Stmt::EnhancedFor(EnhancedForStmt {
2816 leading_comments,
2817 for_span,
2818 paren_span: (open, close),
2819 var_decl: LocalVarDeclStmt {
2820 leading_comments: Vec::new(),
2821 modifiers,
2822 ty,
2823 declarators: vec![VariableDeclarator {
2824 name: Some(name),
2825 dims,
2826 initializer: None,
2827 }],
2828 semi_span: Span::call_site(),
2829 },
2830 colon_span,
2831 iterable,
2832 body: Box::new(body),
2833 }));
2834 }
2835 }
2836 input.set_cursor(saved);
2837 None
2838}
2839
2840fn parse_jump_stmt(
2841 input: &ParseStream,
2842 keyword: TokenKind,
2843 make_stmt: fn(JumpStmt) -> Stmt,
2844 leading_comments: Vec<Comment>,
2845) -> Result<Stmt> {
2846 let keyword_span = input.peek().span;
2847 input.expect(keyword)?;
2848 let label = if input.is_any_ident() && !input.is(&TokenKind::Semicolon) {
2849 let saved = input.cursor();
2850 let ident = input.parse_ident().ok();
2851 if ident.is_some() && (input.is(&TokenKind::Semicolon) || input.is_empty()) {
2852 ident
2853 } else {
2854 input.set_cursor(saved);
2855 None
2856 }
2857 } else {
2858 None
2859 };
2860 input.expect(TokenKind::Semicolon)?;
2861 let semi_span = input.peek().span;
2862 Ok(make_stmt(JumpStmt {
2863 leading_comments,
2864 keyword_span,
2865 label,
2866 semi_span,
2867 }))
2868}
2869
2870fn parse_return_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2871 let return_span = input.peek().span;
2872 input.expect(TokenKind::Return)?;
2873 let value = if input.is(&TokenKind::Semicolon) {
2874 None
2875 } else {
2876 Some(parse_expression(input)?)
2877 };
2878 input.expect(TokenKind::Semicolon)?;
2879 let semi_span = input.peek().span;
2880 Ok(Stmt::Return(ReturnStmt {
2881 leading_comments,
2882 return_span,
2883 value,
2884 semi_span,
2885 }))
2886}
2887
2888fn parse_throw_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2889 let throw_span = input.peek().span;
2890 input.expect(TokenKind::Throw)?;
2891 let expr = parse_expression(input)?;
2892 input.expect(TokenKind::Semicolon)?;
2893 let semi_span = input.peek().span;
2894 Ok(Stmt::Throw(ThrowStmt {
2895 leading_comments,
2896 throw_span,
2897 expr,
2898 semi_span,
2899 }))
2900}
2901
2902fn parse_synchronized_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2903 let synchronized_span = input.peek().span;
2904 input.expect(TokenKind::Synchronized)?;
2905 input.expect(TokenKind::LParen)?;
2906 let open = input.peek().span;
2907 let lock = parse_expression(input)?;
2908 input.expect(TokenKind::RParen)?;
2909 let close = input.peek().span;
2910 let body = parse_block(input, Vec::new())?;
2911 Ok(Stmt::Synchronized(SynchronizedStmt {
2912 leading_comments,
2913 synchronized_span,
2914 paren_span: (open, close),
2915 lock,
2916 body,
2917 }))
2918}
2919
2920fn parse_try_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2921 let try_span = input.peek().span;
2922 input.expect(TokenKind::Try)?;
2923
2924 if input.is(&TokenKind::LParen) {
2925 input.expect(TokenKind::LParen)?;
2927 let open = input.peek().span;
2928 let mut resources = Vec::new();
2929 loop {
2930 let saved = input.cursor();
2931 let modifiers = parse_modifiers(input);
2933 let is_var = input.is(&TokenKind::Var);
2934 let can_start = crate::token::can_start_type(&input.peek().kind);
2935 if is_var || can_start {
2936 let ty_result = if is_var {
2937 let var_span = input.peek().span;
2938 input.next();
2939 Ok(LocalVarType::Var(var_span))
2940 } else {
2941 parse_type(input).map(LocalVarType::Type)
2942 };
2943 if let Ok(ty) = ty_result
2944 && input.is_any_ident()
2945 && let Ok(name) = input.parse_ident()
2946 {
2947 let dims = parse_array_dims(input).unwrap_or_default();
2948 let initializer = if input.eat(&TokenKind::Eq) {
2949 parse_expression(input).ok()
2950 } else {
2951 None
2952 };
2953 let declarators = vec![VariableDeclarator {
2954 name: Some(name),
2955 dims,
2956 initializer,
2957 }];
2958 resources.push(TryResource::Decl(LocalVarDeclStmt {
2959 leading_comments: Vec::new(),
2960 modifiers,
2961 ty,
2962 declarators,
2963 semi_span: Span::call_site(),
2964 }));
2965 if !input.eat(&TokenKind::Semicolon) {
2966 break;
2967 }
2968 if input.is(&TokenKind::RParen) {
2969 break;
2970 }
2971 continue;
2972 }
2973 }
2974 input.set_cursor(saved);
2975 let ident = input.parse_ident()?;
2976 resources.push(TryResource::VarRef(ident));
2977 if !input.eat(&TokenKind::Semicolon) {
2978 break;
2979 }
2980 if input.is(&TokenKind::RParen) {
2981 break;
2982 }
2983 }
2984 input.expect(TokenKind::RParen)?;
2985 let close = input.peek().span;
2986 let block = parse_block(input, Vec::new())?;
2987 let catches = parse_catch_clauses(input)?;
2988 let finally_block = parse_finally_clause(input);
2989 Ok(Stmt::Try(TryStmt::TryWithResources {
2990 leading_comments,
2991 try_span,
2992 paren_span: (open, close),
2993 resources,
2994 block,
2995 catches,
2996 finally_block,
2997 }))
2998 } else {
2999 let block = parse_block(input, Vec::new())?;
3000 let catches = parse_catch_clauses(input)?;
3001 let finally_block = parse_finally_clause(input);
3002 Ok(Stmt::Try(TryStmt::Basic {
3003 leading_comments,
3004 try_span,
3005 block,
3006 catches,
3007 finally_block,
3008 }))
3009 }
3010}
3011
3012fn parse_catch_clauses(input: &ParseStream) -> Result<Vec<CatchClause>> {
3013 let mut clauses = Vec::new();
3014 while input.is(&TokenKind::Catch) {
3015 let catch_span = input.peek().span;
3016 input.next();
3017 input.expect(TokenKind::LParen).ok();
3018 let open = input.peek().span;
3019 let modifiers = parse_modifiers(input);
3020 let mut types = Vec::new();
3021 types.push(parse_type(input)?);
3022 while input.eat(&TokenKind::Pipe) {
3023 types.push(parse_type(input)?);
3024 }
3025 let name = input.parse_ident()?;
3026 input.expect(TokenKind::RParen).ok();
3027 let close = input.peek().span;
3028 let block = parse_block(input, Vec::new())?;
3029 clauses.push(CatchClause {
3030 catch_span,
3031 paren_span: (open, close),
3032 param: CatchParam {
3033 modifiers,
3034 ty: CatchType { types },
3035 name,
3036 },
3037 block,
3038 });
3039 }
3040 Ok(clauses)
3041}
3042
3043fn parse_finally_clause(input: &ParseStream) -> Option<(Span, Block)> {
3044 if input.eat(&TokenKind::Finally) {
3045 let finally_span = input.peek().span;
3046 let block = parse_block(input, Vec::new()).ok()?;
3047 Some((finally_span, block))
3048 } else {
3049 None
3050 }
3051}
3052
3053fn parse_yield_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
3054 let yield_span = input.peek().span;
3055 input.expect(TokenKind::Yield)?;
3056 let value = parse_expression(input)?;
3057 input.expect(TokenKind::Semicolon)?;
3058 let semi_span = input.peek().span;
3059 Ok(Stmt::Yield(YieldStmt {
3060 leading_comments,
3061 yield_span,
3062 value,
3063 semi_span,
3064 }))
3065}
3066
3067fn parse_expression(input: &ParseStream) -> Result<Expr> {
3072 parse_assignment_expr(input)
3073}
3074
3075fn parse_assignment_expr(input: &ParseStream) -> Result<Expr> {
3076 let left = parse_conditional_expr(input)?;
3077
3078 if is_assignment_op(&input.peek().kind) {
3079 let op = parse_assign_op(input)?;
3080 let value = parse_assignment_expr(input)?;
3081 let target = expr_to_assign_target(left)?;
3082 return Ok(Expr::Assign(AssignExpr {
3083 target,
3084 op,
3085 value: Box::new(value),
3086 }));
3087 }
3088
3089 Ok(left)
3090}
3091
3092fn is_assignment_op(kind: &TokenKind) -> bool {
3093 matches!(
3094 kind,
3095 TokenKind::Eq
3096 | TokenKind::PlusEq
3097 | TokenKind::MinusEq
3098 | TokenKind::StarEq
3099 | TokenKind::SlashEq
3100 | TokenKind::AmpEq
3101 | TokenKind::PipeEq
3102 | TokenKind::CaretEq
3103 | TokenKind::PercentEq
3104 | TokenKind::LtLtEq
3105 | TokenKind::GtGtEq
3106 | TokenKind::GtGtGtEq
3107 )
3108}
3109
3110fn parse_assign_op(input: &ParseStream) -> Result<AssignOpToken> {
3111 let span = input.peek().span;
3112 let op = match &input.peek().kind {
3113 TokenKind::Eq => AssignOp::Assign,
3114 TokenKind::PlusEq => AssignOp::AddAssign,
3115 TokenKind::MinusEq => AssignOp::SubAssign,
3116 TokenKind::StarEq => AssignOp::MulAssign,
3117 TokenKind::SlashEq => AssignOp::DivAssign,
3118 TokenKind::AmpEq => AssignOp::AndAssign,
3119 TokenKind::PipeEq => AssignOp::OrAssign,
3120 TokenKind::CaretEq => AssignOp::XorAssign,
3121 TokenKind::PercentEq => AssignOp::RemAssign,
3122 TokenKind::LtLtEq => AssignOp::LShiftAssign,
3123 TokenKind::GtGtEq => AssignOp::RShiftAssign,
3124 TokenKind::GtGtGtEq => AssignOp::URShiftAssign,
3125 _ => {
3126 return Err(crate::error::Error::new(
3127 span,
3128 "expected assignment operator",
3129 ));
3130 }
3131 };
3132 input.next();
3133 Ok(AssignOpToken { op, span })
3134}
3135
3136fn expr_to_assign_target(expr: Expr) -> Result<AssignTarget> {
3137 match expr {
3138 Expr::Ident(i) => Ok(AssignTarget::Ident(i)),
3139 Expr::FieldAccess(f) => Ok(AssignTarget::FieldAccess(f)),
3140 Expr::ArrayAccess(a) => Ok(AssignTarget::ArrayAccess(a)),
3141 _ => Err(crate::error::Error::new(
3142 expr.span(),
3143 "invalid assignment target",
3144 )),
3145 }
3146}
3147
3148fn parse_conditional_expr(input: &ParseStream) -> Result<Expr> {
3149 let expr = parse_binary_expr(input, 0)?;
3150 if input.eat(&TokenKind::Question) {
3151 let question_span = input.peek().span;
3152 let then_expr = parse_expression(input)?;
3153 input.expect(TokenKind::Colon)?;
3154 let colon_span = input.peek().span;
3155 let else_expr = parse_conditional_expr(input)?;
3156 return Ok(Expr::Conditional(ConditionalExpr {
3157 cond: Box::new(expr),
3158 question_span,
3159 then_expr: Box::new(then_expr),
3160 colon_span,
3161 else_expr: Box::new(else_expr),
3162 }));
3163 }
3164 Ok(expr)
3165}
3166
3167fn get_precedence(kind: &TokenKind) -> u8 {
3168 match kind {
3169 TokenKind::PipePipe => 1,
3170 TokenKind::AmpAmp => 2,
3171 TokenKind::Pipe => 3,
3172 TokenKind::Caret => 4,
3173 TokenKind::Amp => 5,
3174 TokenKind::EqEq | TokenKind::BangEq => 6,
3175 TokenKind::Lt
3176 | TokenKind::Gt
3177 | TokenKind::LtEq
3178 | TokenKind::GtEq
3179 | TokenKind::Instanceof => 7,
3180 TokenKind::LtLt | TokenKind::GtGt | TokenKind::GtGtGt => 8,
3181 TokenKind::Plus | TokenKind::Minus => 9,
3182 TokenKind::Star | TokenKind::Slash | TokenKind::Percent => 10,
3183 _ => 0,
3184 }
3185}
3186
3187fn token_to_bin_op(kind: &TokenKind) -> Option<crate::ast::op::BinOp> {
3188 use crate::ast::op::BinOp::*;
3189 Some(match kind {
3190 TokenKind::Plus => Add,
3191 TokenKind::Minus => Sub,
3192 TokenKind::Star => Mul,
3193 TokenKind::Slash => Div,
3194 TokenKind::Percent => Rem,
3195 TokenKind::Amp => And,
3196 TokenKind::Pipe => Or,
3197 TokenKind::Caret => Xor,
3198 TokenKind::LtLt => LShift,
3199 TokenKind::GtGt => RShift,
3200 TokenKind::GtGtGt => URShift,
3201 TokenKind::EqEq => Eq,
3202 TokenKind::BangEq => Ne,
3203 TokenKind::Lt => Lt,
3204 TokenKind::Gt => Gt,
3205 TokenKind::LtEq => Le,
3206 TokenKind::GtEq => Ge,
3207 TokenKind::AmpAmp => LAnd,
3208 TokenKind::PipePipe => LOr,
3209 _ => return None,
3210 })
3211}
3212
3213fn parse_binary_expr(input: &ParseStream, min_prec: u8) -> Result<Expr> {
3214 let mut left = parse_unary_expr(input)?;
3215
3216 loop {
3217 let prec = get_precedence(&input.peek().kind);
3218 if prec == 0 || prec < min_prec {
3219 break;
3220 }
3221
3222 if input.is(&TokenKind::Instanceof) {
3223 let instanceof_span = input.peek().span;
3224 input.next();
3225
3226 let _has_final = input.eat(&TokenKind::Final);
3228
3229 let ty = parse_type(input)?;
3230 let ty_span = ty.span();
3231
3232 if input.is(&TokenKind::LParen) {
3233 input.next(); let mut components = Vec::new();
3236 while !input.is(&TokenKind::RParen) && !input.is_empty() {
3237 components.push(parse_pattern(input)?);
3238 input.eat(&TokenKind::Comma);
3239 }
3240 input.expect(TokenKind::RParen)?;
3241 let end = input.peek().span;
3242 left = Expr::Instanceof(InstanceofExpr {
3243 expr: Box::new(left),
3244 instanceof_span,
3245 pattern: InstanceofPattern::Pattern(Pattern::RecordPattern(RecordPattern {
3246 record_type: ty,
3247 components,
3248 span: ty_span.join(end),
3249 })),
3250 });
3251 continue;
3252 } else if input.is_any_ident() {
3253 let name = input.parse_ident()?;
3255 left = Expr::Instanceof(InstanceofExpr {
3256 expr: Box::new(left),
3257 instanceof_span,
3258 pattern: InstanceofPattern::Pattern(Pattern::TypePattern(TypePattern {
3259 annotations: vec![],
3260 ty,
3261 name: Some(name),
3262 span: ty_span.join(input.peek().span),
3263 })),
3264 });
3265 continue;
3266 } else {
3267 left = Expr::Instanceof(InstanceofExpr {
3268 expr: Box::new(left),
3269 instanceof_span,
3270 pattern: InstanceofPattern::Type(ty),
3271 });
3272 continue;
3273 }
3274 }
3275
3276 let op = match token_to_bin_op(&input.peek().kind) {
3277 Some(op) => op,
3278 None => break,
3279 };
3280 let op_span = input.peek().span;
3281 input.next();
3282
3283 let right = parse_binary_expr(input, prec + 1)?;
3284 left = Expr::Binary(BinaryExpr {
3285 left: Box::new(left),
3286 op: BinOpToken { op, span: op_span },
3287 right: Box::new(right),
3288 });
3289 }
3290
3291 Ok(left)
3292}
3293
3294fn can_start_unary_expr(kind: &TokenKind) -> bool {
3295 matches!(
3296 kind,
3297 TokenKind::Plus
3298 | TokenKind::Minus
3299 | TokenKind::Bang
3300 | TokenKind::Tilde
3301 | TokenKind::PlusPlus
3302 | TokenKind::MinusMinus
3303 | TokenKind::LParen
3304 | TokenKind::New
3305 | TokenKind::Super
3306 | TokenKind::This
3307 | TokenKind::IntegerLit(_)
3308 | TokenKind::FloatLit(_)
3309 | TokenKind::StringLit(_)
3310 | TokenKind::CharLit(_)
3311 | TokenKind::BoolLit(_)
3312 | TokenKind::NullLit
3313 | TokenKind::Ident(_)
3314 | TokenKind::Record
3315 | TokenKind::Sealed
3316 | TokenKind::Var
3317 | TokenKind::Yield
3318 | TokenKind::Open
3319 | TokenKind::Provides
3320 | TokenKind::Requires
3321 | TokenKind::Uses
3322 | TokenKind::With
3323 | TokenKind::When
3324 | TokenKind::To
3325 | TokenKind::Exports
3326 | TokenKind::Opens
3327 | TokenKind::Transitive
3328 | TokenKind::Byte
3329 | TokenKind::Short
3330 | TokenKind::Int
3331 | TokenKind::Long
3332 | TokenKind::Char
3333 | TokenKind::Float
3334 | TokenKind::Double
3335 | TokenKind::Boolean
3336 | TokenKind::Switch
3337 )
3338}
3339
3340fn token_to_unary_op(kind: &TokenKind) -> Option<UnaryOp> {
3341 match kind {
3342 TokenKind::Minus => Some(UnaryOp::Neg),
3343 TokenKind::Bang => Some(UnaryOp::Not),
3344 TokenKind::Tilde => Some(UnaryOp::BitNot),
3345 TokenKind::PlusPlus => Some(UnaryOp::PreInc),
3346 TokenKind::MinusMinus => Some(UnaryOp::PreDec),
3347 _ => None,
3348 }
3349}
3350
3351fn parse_unary_expr(input: &ParseStream) -> Result<Expr> {
3352 let span = input.peek().span;
3353 if input.is(&TokenKind::Plus) {
3354 input.next();
3355 return parse_unary_expr(input);
3356 }
3357 if let Some(op) = token_to_unary_op(&input.peek().kind) {
3358 input.next();
3359 let expr = parse_unary_expr(input)?;
3360 return Ok(Expr::Unary(UnaryExpr {
3361 op,
3362 op_span: span,
3363 expr: Box::new(expr),
3364 is_postfix: false,
3365 }));
3366 }
3367 parse_postfix_expr(input)
3368}
3369
3370fn parse_postfix_expr(input: &ParseStream) -> Result<Expr> {
3371 let mut expr = parse_primary_expr(input)?;
3372
3373 loop {
3374 match &input.peek().kind {
3375 TokenKind::Dot => {
3376 let dot_span = input.peek().span;
3377 input.next();
3378 if input.is(&TokenKind::New) {
3379 let new_span = input.peek().span;
3381 input.next();
3382 let type_args = parse_optional_type_arguments(input);
3383 let class_type = parse_path(input)?;
3384 input.expect(TokenKind::LParen)?;
3385 let open = input.peek().span;
3386 let args = input.parse_terminated(parse_expression)?;
3387 input.expect(TokenKind::RParen)?;
3388 let close = input.peek().span;
3389 let body = if input.is(&TokenKind::LBrace) {
3390 let dl = parse_class_body_decl_list(input)?;
3391 Some(dl)
3392 } else {
3393 None
3394 };
3395 expr = Expr::NewClass(NewClassExpr {
3396 new_span,
3397 type_args,
3398 class_type,
3399 paren_span: (open, close),
3400 args,
3401 body,
3402 });
3403 } else if input.is(&TokenKind::This) {
3404 let this_span = input.peek().span;
3405 input.next();
3406 expr = Expr::FieldAccess(FieldAccessExpr {
3407 target: Box::new(expr),
3408 dot_span,
3409 field: Ident::new("this".to_string(), this_span),
3410 });
3411 } else if input.is(&TokenKind::Class) {
3412 let class_span = input.peek().span;
3413 input.next();
3414 let ty = expr_to_type(&expr)?;
3415 expr = Expr::ClassLit {
3416 type_expr: Box::new(ty),
3417 dot_span,
3418 class_span,
3419 };
3420 } else if input.is(&TokenKind::Super) {
3421 let super_span = input.peek().span;
3422 input.next();
3423 if input.is(&TokenKind::ColonColon) {
3424 let colon_colon_span = input.peek().span;
3425 input.next();
3426 let type_args = parse_optional_type_arguments(input);
3427 let method_name = input.parse_ident()?;
3428 expr = Expr::MethodRef(MethodRefExpr {
3429 target: MethodRefTarget::SuperFromType {
3430 type_name: expr_to_path(expr)?,
3431 dot_span,
3432 super_span,
3433 },
3434 colon_colon_span,
3435 type_args,
3436 method_name,
3437 });
3438 } else if input.is(&TokenKind::Dot) {
3439 expr = Expr::FieldAccess(FieldAccessExpr {
3443 target: Box::new(expr),
3444 dot_span,
3445 field: Ident::new("super".to_string(), super_span),
3446 });
3447 } else {
3448 return Err(crate::error::Error::new(super_span, "unexpected super"));
3449 }
3450 } else if input.is(&TokenKind::New) {
3451 let _ = input.next();
3452 continue;
3454 } else if input.is(&TokenKind::Lt) {
3455 let type_args = parse_type_arguments(input)?;
3457 let method = input.parse_ident()?;
3458 input.expect(TokenKind::LParen)?;
3459 let open = input.peek().span;
3460 let args = input.parse_terminated(parse_expression)?;
3461 input.expect(TokenKind::RParen)?;
3462 let close = input.peek().span;
3463 expr = Expr::MethodCall(MethodCallExpr {
3464 receiver: Some(Box::new(expr)),
3465 type_args: Some(type_args),
3466 method,
3467 paren_span: (open, close),
3468 args,
3469 });
3470 } else {
3471 let field = input.parse_ident().unwrap_or_else(|_| {
3472 let sp = input.peek().span;
3473 let name = format!("{}", input.peek().kind);
3474 input.next();
3475 Ident::new(name, sp)
3476 });
3477 expr = Expr::FieldAccess(FieldAccessExpr {
3478 target: Box::new(expr),
3479 dot_span,
3480 field,
3481 });
3482 }
3483 }
3484 TokenKind::LParen => {
3485 let open = input.peek().span;
3488 input.next();
3489 let args = input.parse_terminated(parse_expression)?;
3490 input.expect(TokenKind::RParen)?;
3491 let close = input.peek().span;
3492
3493 let (method, receiver) = match &expr {
3496 Expr::Ident(name) => (name.clone(), None),
3497 Expr::FieldAccess(f) => {
3498 (f.field.clone(), Some(Box::new(f.target.as_ref().clone())))
3499 }
3500 _ => return Err(crate::error::Error::new(open, "expected method name")),
3501 };
3502
3503 expr = Expr::MethodCall(MethodCallExpr {
3508 receiver,
3509 type_args: None,
3510 method,
3511 paren_span: (open, close),
3512 args,
3513 });
3514 }
3515 TokenKind::LBracket => {
3516 let open = input.peek().span;
3517 input.next();
3518 if input.is(&TokenKind::RBracket) {
3521 input.next();
3522 let close = input.peek().span;
3523 let mut dims = vec![crate::ast::ArrayDim {
3525 bracket_span: (open, close),
3526 annotations: vec![],
3527 }];
3528 while input.is(&TokenKind::LBracket) {
3529 let d_open = input.peek().span;
3530 input.next();
3531 input.expect(TokenKind::RBracket)?;
3532 let d_close = input.peek().span;
3533 dims.push(crate::ast::ArrayDim {
3534 bracket_span: (d_open, d_close),
3535 annotations: vec![],
3536 });
3537 }
3538 if input.is(&TokenKind::Dot) && input.look_ahead(1).kind == TokenKind::Class {
3540 let base_ty = expr_to_type(&expr)?;
3542 let span = base_ty.span().join(dims.last().unwrap().bracket_span.1);
3543 let ty = Type::Reference(ReferenceType::Array(ArrayType {
3544 elem_type: Box::new(base_ty),
3545 dims,
3546 span,
3547 }));
3548 let dot_span = input.peek().span;
3549 input.next(); let class_span = input.peek().span;
3551 input.next(); expr = Expr::ClassLit {
3553 type_expr: Box::new(ty),
3554 dot_span,
3555 class_span,
3556 };
3557 } else if input.is(&TokenKind::ColonColon) {
3558 } else {
3565 expr =
3568 Expr::Ident(crate::ident::Ident::new("_array_type_".to_string(), open));
3569 }
3570 } else {
3571 let index = parse_expression(input)?;
3572 input.expect(TokenKind::RBracket)?;
3573 let close = input.peek().span;
3574 expr = Expr::ArrayAccess(ArrayAccessExpr {
3575 array: Box::new(expr),
3576 index: Box::new(index),
3577 bracket_span: (open, close),
3578 });
3579 }
3580 }
3581 TokenKind::PlusPlus => {
3582 let op_span = input.peek().span;
3583 input.next();
3584 expr = Expr::Unary(UnaryExpr {
3585 op: UnaryOp::PostInc,
3586 op_span,
3587 expr: Box::new(expr),
3588 is_postfix: true,
3589 });
3590 }
3591 TokenKind::MinusMinus => {
3592 let op_span = input.peek().span;
3593 input.next();
3594 expr = Expr::Unary(UnaryExpr {
3595 op: UnaryOp::PostDec,
3596 op_span,
3597 expr: Box::new(expr),
3598 is_postfix: true,
3599 });
3600 }
3601 TokenKind::ColonColon => {
3602 let colon_colon_span = input.peek().span;
3603 input.next();
3604 let type_args = parse_optional_type_arguments(input);
3605 if input.is(&TokenKind::New) {
3606 let method_name = Ident::new("new".to_string(), input.peek().span);
3608 input.next();
3609 expr = Expr::MethodRef(MethodRefExpr {
3610 target: MethodRefTarget::Type(expr_to_path(expr)?),
3611 colon_colon_span,
3612 type_args,
3613 method_name,
3614 });
3615 } else {
3616 let method_name = input.parse_ident()?;
3617 match &expr {
3618 Expr::Ident(_) => {
3619 expr = Expr::MethodRef(MethodRefExpr {
3620 target: MethodRefTarget::Type(expr_to_path(expr)?),
3621 colon_colon_span,
3622 type_args,
3623 method_name,
3624 });
3625 }
3626 _ => {
3627 expr = Expr::MethodRef(MethodRefExpr {
3628 target: MethodRefTarget::Expr(Box::new(expr)),
3629 colon_colon_span,
3630 type_args,
3631 method_name,
3632 });
3633 }
3634 }
3635 }
3636 }
3637 _ => break,
3638 }
3639 }
3640
3641 Ok(expr)
3642}
3643
3644fn expr_to_type(expr: &Expr) -> Result<Type> {
3645 match expr {
3646 Expr::Ident(i) => match i.name.as_str() {
3647 "byte" => Ok(Type::Primitive(PrimitiveType::Byte)),
3648 "short" => Ok(Type::Primitive(PrimitiveType::Short)),
3649 "int" => Ok(Type::Primitive(PrimitiveType::Int)),
3650 "long" => Ok(Type::Primitive(PrimitiveType::Long)),
3651 "char" => Ok(Type::Primitive(PrimitiveType::Char)),
3652 "float" => Ok(Type::Primitive(PrimitiveType::Float)),
3653 "double" => Ok(Type::Primitive(PrimitiveType::Double)),
3654 "boolean" => Ok(Type::Primitive(PrimitiveType::Boolean)),
3655 "void" => Ok(Type::Void(i.span())),
3656 _ => Ok(Type::Reference(ReferenceType::ClassOrInterfaceType(
3657 ClassOrInterfaceType {
3658 path: Path::from_ident(i.clone()),
3659 annotations_prefix: vec![],
3660 },
3661 ))),
3662 },
3663 Expr::FieldAccess(_) => {
3664 let path = expr_to_path(expr.clone())?;
3665 Ok(Type::Reference(ReferenceType::ClassOrInterfaceType(
3666 ClassOrInterfaceType {
3667 path,
3668 annotations_prefix: vec![],
3669 },
3670 )))
3671 }
3672 _ => Err(crate::error::Error::new(expr.span(), "expected type")),
3673 }
3674}
3675
3676fn expr_to_path(expr: Expr) -> Result<Path> {
3677 match expr {
3678 Expr::Ident(i) => Ok(Path::from_ident(i)),
3679 Expr::FieldAccess(f) => {
3680 let mut target_path = expr_to_path(*f.target)?;
3681 target_path.segments.push(PathSegment {
3682 ident: f.field,
3683 args: None,
3684 });
3685 Ok(target_path)
3686 }
3687 _ => Err(crate::error::Error::new(expr.span(), "expected type name")),
3688 }
3689}
3690
3691fn parse_primary_expr(input: &ParseStream) -> Result<Expr> {
3692 let span = input.peek().span;
3693
3694 if input.is(&TokenKind::LParen) {
3696 let open = span;
3697 input.next();
3698
3699 let saved = input.cursor();
3701
3702 if let Ok(ty) = parse_type(input) {
3704 let mut intersection_types = Vec::new();
3706 while input.eat(&TokenKind::Amp) {
3707 if let Ok(ty) = parse_type(input) {
3708 intersection_types.push(ty);
3709 } else {
3710 break;
3711 }
3712 }
3713
3714 if input.is(&TokenKind::RParen) {
3715 let next_after_rparen = input.look_ahead(1);
3718 let can_be_cast = can_start_unary_expr(&next_after_rparen.kind);
3719
3720 if can_be_cast {
3721 input.next();
3722 let close = input.peek().span;
3723 if input.is(&TokenKind::Arrow) {
3726 let arrow_span = input.peek().span;
3727 input.next();
3728 let body = parse_lambda_body(input)?;
3729 return Ok(Expr::Lambda(LambdaExpr {
3730 params: LambdaParams::List {
3731 paren_span: (open, close),
3732 params: vec![LambdaParam {
3733 modifiers: vec![],
3734 ty,
3735 name: crate::ident::Ident::new("_".to_string(), span),
3736 }],
3737 },
3738 arrow_span,
3739 body,
3740 span: open.join(input.peek().span),
3741 }));
3742 }
3743 let expr = parse_unary_expr(input)?;
3744 return Ok(Expr::Cast(CastExpr {
3747 paren_span: (open, close),
3748 target_type: ty,
3749 expr: Box::new(expr),
3750 }));
3751 }
3752 }
3753 }
3754
3755 input.set_cursor(saved);
3756
3757 {
3761 let lambda_saved = input.cursor();
3762 let mut depth = 1;
3763 let mut offset = 0;
3764 loop {
3765 let tok = input.look_ahead(offset);
3766 match &tok.kind {
3767 TokenKind::LParen => depth += 1,
3768 TokenKind::RParen => {
3769 depth -= 1;
3770 if depth == 0 {
3771 break;
3772 }
3773 }
3774 TokenKind::Eof => break,
3775 _ => {}
3776 }
3777 offset += 1;
3778 }
3779 if input.look_ahead(offset + 1).kind == TokenKind::Arrow {
3782 let params = parse_lambda_params_after_lparen(input)?;
3785 let arrow_span = input.peek().span;
3786 input.next();
3787 let body = parse_lambda_body(input)?;
3788 return Ok(Expr::Lambda(LambdaExpr {
3789 params,
3790 arrow_span,
3791 body,
3792 span: open.join(input.peek().span),
3793 }));
3794 }
3795 input.set_cursor(lambda_saved);
3796 }
3797
3798 let expr = parse_expression(input)?;
3800 input.expect(TokenKind::RParen)?;
3801 let close = input.peek().span;
3802 return Ok(Expr::Paren {
3803 paren_span: (open, close),
3804 expr: Box::new(expr),
3805 });
3806 }
3807
3808 match &input.peek().kind {
3809 TokenKind::IntegerLit(v) => {
3810 let value = v.clone();
3811 let sp = input.peek().span;
3812 input.next();
3813 Ok(Expr::Literal(Lit::Int(IntLit { value, span: sp })))
3814 }
3815 TokenKind::FloatLit(v) => {
3816 let value = v.clone();
3817 let sp = input.peek().span;
3818 input.next();
3819 Ok(Expr::Literal(Lit::Float(FloatLit { value, span: sp })))
3820 }
3821 TokenKind::BoolLit(b) => {
3822 let value = *b;
3823 let sp = input.peek().span;
3824 input.next();
3825 Ok(Expr::Literal(Lit::Bool(BoolLit { value, span: sp })))
3826 }
3827 TokenKind::CharLit(v) => {
3828 let value = v.clone();
3829 let sp = input.peek().span;
3830 input.next();
3831 Ok(Expr::Literal(Lit::Char(CharLit { value, span: sp })))
3832 }
3833 TokenKind::StringLit(v) => {
3834 let value = v.clone();
3835 let sp = input.peek().span;
3836 input.next();
3837 Ok(Expr::Literal(Lit::Str(StrLit { value, span: sp })))
3838 }
3839 TokenKind::NullLit => {
3840 let sp = input.peek().span;
3841 input.next();
3842 Ok(Expr::Literal(Lit::Null(NullLit { span: sp })))
3843 }
3844 TokenKind::This => {
3845 let sp = input.peek().span;
3846 input.next();
3847 Ok(Expr::This(sp))
3848 }
3849 TokenKind::Super => {
3850 let sp = input.peek().span;
3851 input.next();
3852 Ok(Expr::Super(sp))
3853 }
3854 TokenKind::New => parse_new_expr(input),
3855 TokenKind::Switch => parse_switch_expr(input),
3856 TokenKind::LBrace => Ok(Expr::ArrayInit(parse_array_init(input)?)),
3857 _ => {
3858 if input.is_any_ident()
3861 || is_contextual_type_keyword(&input.peek().kind)
3862 || is_primitive_type_token(&input.peek().kind)
3863 || input.is(&TokenKind::Void)
3864 {
3865 let ident = input.parse_ident()?;
3866 if input.is(&TokenKind::Arrow) {
3868 let ident_span = ident.span;
3869 let arrow_span = input.peek().span;
3870 input.next();
3871 let body = parse_lambda_body(input)?;
3872 let end = body.span();
3873 return Ok(Expr::Lambda(LambdaExpr {
3874 params: LambdaParams::Single(ident),
3875 arrow_span,
3876 body,
3877 span: ident_span.join(end),
3878 }));
3879 }
3880 if input.is(&TokenKind::Lt) {
3883 let saved = input.save_state();
3884 if let Ok(type_args) = parse_type_arguments(input) {
3885 while input.is(&TokenKind::LBracket)
3888 && input.look_ahead(1).kind == TokenKind::RBracket
3889 {
3890 input.next(); input.next(); }
3893 if input.is(&TokenKind::ColonColon) {
3894 let colon_colon_span = input.peek().span;
3895 input.next();
3896 let type_args2 = parse_optional_type_arguments(input);
3897 let method_name = if input.is(&TokenKind::New) {
3898 let name = Ident::new("new".to_string(), input.peek().span);
3899 input.next();
3900 name
3901 } else {
3902 input.parse_ident()?
3903 };
3904 let path = Path {
3905 segments: vec![PathSegment {
3906 ident,
3907 args: Some(type_args),
3908 }],
3909 span: span.join(input.peek().span),
3910 };
3911 return Ok(Expr::MethodRef(MethodRefExpr {
3912 target: MethodRefTarget::Type(path),
3913 colon_colon_span,
3914 type_args: type_args2,
3915 method_name,
3916 }));
3917 }
3918 }
3919 input.restore_state(saved);
3920 }
3921 Ok(Expr::Ident(ident))
3922 } else {
3923 Err(crate::error::Error::new(span, "expected expression"))
3924 }
3925 }
3926 }
3927}
3928
3929fn parse_lambda_params_after_lparen(input: &ParseStream) -> Result<LambdaParams> {
3930 let open = input.peek().span;
3931 let mut params = Vec::new();
3932 let mut idents = Vec::new();
3933
3934 while !input.is(&TokenKind::RParen) && !input.is_empty() {
3935 let saved = input.cursor();
3936 if let Ok(ty) = parse_type(input) {
3938 if input.is_any_ident() {
3939 let name = input.parse_ident()?;
3940 params.push(LambdaParam {
3941 modifiers: vec![],
3942 ty,
3943 name,
3944 });
3945 if !input.eat(&TokenKind::Comma) {
3946 break;
3947 }
3948 continue;
3949 }
3950 input.set_cursor(saved);
3951 } else {
3952 input.set_cursor(saved);
3953 }
3954 let ident = input.parse_ident()?;
3956 idents.push(ident);
3957 if !input.eat(&TokenKind::Comma) {
3958 break;
3959 }
3960 }
3961
3962 input.expect(TokenKind::RParen)?;
3963 let close = input.peek().span;
3964
3965 if !params.is_empty() && idents.is_empty() {
3966 Ok(LambdaParams::List {
3967 paren_span: (open, close),
3968 params,
3969 })
3970 } else if params.is_empty() && !idents.is_empty() {
3971 Ok(LambdaParams::IdentList {
3972 paren_span: (open, close),
3973 idents,
3974 })
3975 } else if params.is_empty() && idents.is_empty() {
3976 Ok(LambdaParams::IdentList {
3977 paren_span: (open, close),
3978 idents: vec![],
3979 })
3980 } else {
3981 Ok(LambdaParams::IdentList {
3982 paren_span: (open, close),
3983 idents,
3984 })
3985 }
3986}
3987
3988fn parse_lambda_body(input: &ParseStream) -> Result<LambdaBody> {
3989 if input.is(&TokenKind::LBrace) {
3990 Ok(LambdaBody::Block(parse_block(input, Vec::new())?))
3991 } else {
3992 Ok(LambdaBody::Expr(Box::new(parse_expression(input)?)))
3993 }
3994}
3995
3996fn parse_new_expr(input: &ParseStream) -> Result<Expr> {
3997 let new_span = input.peek().span;
3998 input.expect(TokenKind::New)?;
3999 let type_args = parse_optional_type_arguments(input);
4000
4001 let annotations = parse_type_annotations(input);
4003 let base_type = if is_primitive_type_token(&input.peek().kind) {
4004 let prim = parse_primitive_type(input)?;
4005 Type::Primitive(prim)
4006 } else if input.is_any_ident() || is_contextual_type_keyword(&input.peek().kind) {
4007 let path = parse_path(input)?;
4008 Type::Reference(ReferenceType::ClassOrInterfaceType(ClassOrInterfaceType {
4009 path,
4010 annotations_prefix: annotations,
4011 }))
4012 } else {
4013 return Err(crate::error::Error::new(
4014 new_span,
4015 "expected type after new",
4016 ));
4017 };
4018
4019 if input.is(&TokenKind::LBracket) {
4021 let mut dim_exprs = Vec::new();
4022 let mut dims = Vec::new();
4023
4024 while input.is(&TokenKind::LBracket) {
4025 let open = input.peek().span;
4026 input.next();
4027 if input.is(&TokenKind::RBracket) {
4028 input.next();
4029 let close = input.peek().span;
4030 dims.push(ArrayDim {
4031 bracket_span: (open, close),
4032 annotations: Vec::new(),
4033 });
4034 } else {
4035 let anns = parse_type_annotations(input);
4036 let expr = parse_expression(input)?;
4037 input.expect(TokenKind::RBracket)?;
4038 let close = input.peek().span;
4039 dim_exprs.push(ArrayDimExpr {
4040 annotations: anns,
4041 bracket_span: (open, close),
4042 expr: Box::new(expr),
4043 });
4044 }
4045 }
4046
4047 let initializer = if input.is(&TokenKind::LBrace) {
4048 Some(parse_array_init(input)?)
4049 } else {
4050 None
4051 };
4052
4053 return Ok(Expr::ArrayNew(ArrayNewExpr {
4054 new_span,
4055 elem_type: base_type,
4056 dim_exprs,
4057 dims,
4058 initializer,
4059 }));
4060 }
4061
4062 if input.is(&TokenKind::LParen) || input.is(&TokenKind::LBrace) {
4064 let class_type = match &base_type {
4065 Type::Reference(ReferenceType::ClassOrInterfaceType(cit)) => cit.path.clone(),
4066 _ => {
4067 return Err(crate::error::Error::new(
4068 input.peek().span,
4069 "expected class type",
4070 ));
4071 }
4072 };
4073
4074 if input.is(&TokenKind::LParen) {
4075 input.expect(TokenKind::LParen)?;
4076 let open = input.peek().span;
4077 let args = input.parse_terminated(parse_expression)?;
4078 input.expect(TokenKind::RParen)?;
4079 let close = input.peek().span;
4080 let body = if input.is(&TokenKind::LBrace) {
4081 let dl = parse_class_body_decl_list(input)?;
4082 Some(dl)
4083 } else {
4084 None
4085 };
4086 return Ok(Expr::NewClass(NewClassExpr {
4087 new_span,
4088 type_args,
4089 class_type,
4090 paren_span: (open, close),
4091 args,
4092 body,
4093 }));
4094 }
4095
4096 let dl = parse_class_body_decl_list(input)?;
4098 let body = dl;
4099 return Ok(Expr::NewClass(NewClassExpr {
4100 new_span,
4101 type_args,
4102 class_type,
4103 paren_span: (Span::call_site(), Span::call_site()),
4104 args: Vec::new(),
4105 body: Some(body),
4106 }));
4107 }
4108
4109 Err(crate::error::Error::new(
4110 new_span,
4111 "expected type after new",
4112 ))
4113}
4114
4115fn parse_switch_expr(input: &ParseStream) -> Result<Expr> {
4116 let switch_span = input.peek().span;
4117 input.expect(TokenKind::Switch)?;
4118 input.expect(TokenKind::LParen)?;
4119 let open = input.peek().span;
4120 let selector = parse_expression(input)?;
4121 input.expect(TokenKind::RParen)?;
4122 let close = input.peek().span;
4123 input.expect(TokenKind::LBrace)?;
4124 let brace_open = input.peek().span;
4125 let mut cases = Vec::new();
4126 while !input.is(&TokenKind::RBrace) && !input.is_empty() {
4127 cases.push(parse_switch_arm(input)?);
4128 }
4129 input.expect(TokenKind::RBrace)?;
4130 let brace_close = input.peek().span;
4131 Ok(Expr::Switch(SwitchExpr {
4132 switch_span,
4133 paren_span: (open, close),
4134 selector: Box::new(selector),
4135 brace_span: (brace_open, brace_close),
4136 cases,
4137 }))
4138}
4139
4140fn parse_switch_arm(input: &ParseStream) -> Result<SwitchArm> {
4141 let labels = parse_switch_labels(input)?;
4142 let label = labels
4143 .into_iter()
4144 .next()
4145 .ok_or_else(|| crate::error::Error::new(input.peek().span, "expected case or default"))?;
4146
4147 if input.eat(&TokenKind::Arrow) {
4148 let arrow = input.peek().span;
4149 if input.is(&TokenKind::Throw) {
4150 let _throw_span = input.peek().span;
4151 input.next();
4152 let expr = parse_expression(input)?;
4153 input.expect(TokenKind::Semicolon)?;
4154 Ok(SwitchArm::Throw(label, arrow, expr))
4155 } else if input.is(&TokenKind::LBrace) {
4156 let block = parse_block(input, Vec::new())?;
4157 Ok(SwitchArm::Block(label, arrow, block))
4158 } else {
4159 let expr = parse_expression(input)?;
4160 input.expect(TokenKind::Semicolon)?;
4161 Ok(SwitchArm::Expr(label, arrow, expr))
4162 }
4163 } else {
4164 input.expect(TokenKind::Colon)?;
4165 let mut stmts = Vec::new();
4166 while !input.is_empty() {
4167 if is_switch_label_start(input) || input.is(&TokenKind::RBrace) {
4168 break;
4169 }
4170 stmts.push(parse_statement(input)?);
4171 }
4172 Ok(SwitchArm::Colon(label, stmts))
4173 }
4174}
4175
4176fn parse_pattern(input: &ParseStream) -> Result<Pattern> {
4181 let annotations = parse_annotations(input)?;
4182
4183 let ty = parse_type(input)?;
4186
4187 if input.is(&TokenKind::LParen) {
4188 input.next();
4190 let mut components = Vec::new();
4191 while !input.is(&TokenKind::RParen) && !input.is_empty() {
4192 components.push(parse_pattern(input)?);
4193 input.eat(&TokenKind::Comma);
4194 }
4195 input.expect(TokenKind::RParen)?;
4196 let start = annotations.first().map(|a| a.span()).unwrap_or(ty.span());
4197 let end = input.peek().span;
4198 Ok(Pattern::RecordPattern(RecordPattern {
4199 record_type: ty,
4200 components,
4201 span: start.join(end),
4202 }))
4203 } else {
4204 let name = input.parse_ident().ok();
4206 let start = annotations.first().map(|a| a.span()).unwrap_or(ty.span());
4207 let end = name.as_ref().map(|n| n.span()).unwrap_or(ty.span());
4208 Ok(Pattern::TypePattern(TypePattern {
4209 annotations,
4210 ty,
4211 name,
4212 span: start.join(end),
4213 }))
4214 }
4215}