1use rajac_ast::*;
2#[allow(unused_imports)]
3use rajac_base::file_path::FilePath;
4use rajac_base::shared_string::SharedString;
5use rajac_diagnostics::Diagnostics;
6use rajac_lexer::Lexer;
7use rajac_token::{Token, TokenKind};
8use rajac_types::Ident;
9use std::collections::VecDeque;
10
11pub struct ParseResult {
13 pub ast: Ast,
14 pub arena: AstArena,
15 pub diagnostics: Diagnostics,
16}
17
18pub struct Parser<'a> {
19 pub lexer: Lexer<'a>,
20 pub source: &'a str,
21 pub current: Token,
22 #[allow(dead_code)]
23 tokens: VecDeque<Token>,
24 pub arena: AstArena,
25 in_interface: bool,
26}
27
28impl<'a> Parser<'a> {
29 pub fn new(mut lexer: Lexer<'a>, source: &'a str) -> Self {
30 let mut tokens = VecDeque::new();
31 if let Some(token) = lexer.next() {
33 tokens.push_back(token);
34 }
35 let current = tokens.pop_front().unwrap_or(Token {
36 kind: TokenKind::Eof,
37 span: 0..0,
38 });
39
40 Self {
41 lexer,
42 source,
43 current,
44 tokens,
45 arena: AstArena::new(),
46 in_interface: false,
47 }
48 }
49
50 pub fn bump(&mut self) {
54 if self.current.kind != TokenKind::Eof {
55 self.fill_lookahead(1);
56 if let Some(token) = self.tokens.pop_front() {
57 self.current = token;
58 } else {
59 self.current = Token {
60 kind: TokenKind::Eof,
61 span: self.source.len()..self.source.len(),
62 };
63 }
64 }
65 }
66
67 pub fn peek(&self) -> TokenKind {
69 self.current.kind
70 }
71
72 pub fn peek_n(&mut self, n: usize) -> TokenKind {
74 if n == 0 {
75 return self.peek();
76 }
77
78 self.fill_lookahead(n);
79 self.tokens
80 .get(n - 1)
81 .map(|token| token.kind)
82 .unwrap_or(TokenKind::Eof)
83 }
84
85 fn current_span(&self) -> Span {
87 Span(self.current.span.clone())
88 }
89
90 pub fn ident_text(&self) -> rajac_base::shared_string::SharedString {
92 rajac_base::shared_string::SharedString::new(&self.source[self.current.span.clone()])
93 }
94
95 pub fn is(&self, kind: TokenKind) -> bool {
97 self.peek() == kind
98 }
99
100 pub fn expect(&mut self, kind: TokenKind) -> Span {
102 let span = self.current_span();
103 if self.peek() == kind {
104 self.bump();
105 }
106 span
107 }
108
109 pub fn consume(&mut self, kind: TokenKind) -> bool {
111 if self.peek() == kind {
112 self.bump();
113 true
114 } else {
115 false
116 }
117 }
118
119 fn fill_lookahead(&mut self, count: usize) {
120 while self.tokens.len() < count {
121 let Some(token) = self.lexer.next() else {
122 break;
123 };
124 self.tokens.push_back(token);
125 }
126 }
127
128 pub fn parse_compilation_unit(mut self) -> ParseResult {
131 let mut ast = Ast::new(SharedString::new(self.source));
132
133 if self.is(TokenKind::KwPackage) {
135 ast.package = self.parse_package_decl();
136 }
137
138 while self.is(TokenKind::KwImport) {
140 ast.imports.push(self.parse_import_decl());
141 }
142
143 while !self.is(TokenKind::Eof) {
145 if let Some(class_id) = self.parse_class_decl() {
146 ast.classes.push(class_id);
147 } else {
148 self.bump();
150 }
151 }
152
153 ParseResult {
154 ast,
155 arena: self.arena,
156 diagnostics: self.lexer.take_diagnostics(),
157 }
158 }
159
160 fn parse_package_decl(&mut self) -> Option<PackageDecl> {
163 self.expect(TokenKind::KwPackage);
164 let name = self.parse_qualified_name()?;
165 self.expect(TokenKind::Semi);
166 Some(PackageDecl { name })
167 }
168
169 fn parse_import_decl(&mut self) -> ImportDecl {
170 self.expect(TokenKind::KwImport);
171 let is_static = self.consume(TokenKind::KwStatic);
172 let name = self
173 .parse_qualified_name()
174 .unwrap_or_else(|| QualifiedName::new(vec![SharedString::new("error")]));
175 let is_on_demand = self.consume(TokenKind::Dot) && self.consume(TokenKind::Star);
176 self.expect(TokenKind::Semi);
177 ImportDecl {
178 name,
179 is_static,
180 is_on_demand,
181 }
182 }
183
184 fn parse_qualified_name(&mut self) -> Option<QualifiedName> {
185 let mut segments = Vec::new();
186 if self.peek() == TokenKind::Ident {
187 segments.push(self.ident_text());
188 self.bump();
189 while self.consume(TokenKind::Dot) {
190 if self.peek() == TokenKind::Ident {
191 segments.push(self.ident_text());
192 self.bump();
193 } else {
194 break;
195 }
196 }
197 Some(QualifiedName::new(segments))
198 } else {
199 None
200 }
201 }
202
203 fn parse_modifiers(&mut self) -> Modifiers {
204 let mut flags = 0u32;
205 loop {
206 match self.peek() {
207 TokenKind::KwPublic => {
208 flags |= Modifiers::PUBLIC;
209 self.bump();
210 }
211 TokenKind::KwPrivate => {
212 flags |= Modifiers::PRIVATE;
213 self.bump();
214 }
215 TokenKind::KwProtected => {
216 flags |= Modifiers::PROTECTED;
217 self.bump();
218 }
219 TokenKind::KwStatic => {
220 flags |= Modifiers::STATIC;
221 self.bump();
222 }
223 TokenKind::KwFinal => {
224 flags |= Modifiers::FINAL;
225 self.bump();
226 }
227 TokenKind::KwAbstract => {
228 flags |= Modifiers::ABSTRACT;
229 self.bump();
230 }
231 TokenKind::KwSynchronized => {
232 flags |= Modifiers::SYNCHRONIZED;
233 self.bump();
234 }
235 TokenKind::KwVolatile => {
236 flags |= Modifiers::VOLATILE;
237 self.bump();
238 }
239 TokenKind::KwTransient => {
240 flags |= Modifiers::TRANSIENT;
241 self.bump();
242 }
243 TokenKind::KwNative => {
244 flags |= Modifiers::NATIVE;
245 self.bump();
246 }
247 TokenKind::KwStrictfp => {
248 flags |= Modifiers::STRICTFP;
249 self.bump();
250 }
251 _ => break,
252 }
253 }
254 Modifiers(flags)
255 }
256
257 fn parse_class_decl(&mut self) -> Option<ClassDeclId> {
258 let modifiers = self.parse_modifiers();
259
260 let kind = match self.peek() {
261 TokenKind::KwClass => {
262 self.bump();
263 ClassKind::Class
264 }
265 TokenKind::KwInterface => {
266 self.bump();
267 ClassKind::Interface
268 }
269 TokenKind::KwEnum => {
270 self.bump();
271 ClassKind::Enum
272 }
273 TokenKind::KwRecord => {
274 self.bump();
275 ClassKind::Record
276 }
277 _ => return None,
278 };
279
280 let name = if self.peek() == TokenKind::Ident {
282 Ident::new(self.ident_text())
283 } else {
284 return None;
285 };
286 self.bump();
287
288 let type_params = if self.is(TokenKind::Lt) {
290 self.parse_type_params()
291 } else {
292 Vec::new()
293 };
294
295 if matches!(kind, ClassKind::Enum) {
296 return self.parse_enum_decl_with_name(name, modifiers);
297 }
298
299 let extends = if self.consume(TokenKind::KwExtends) {
301 self.parse_type()
302 } else {
303 None
304 };
305
306 let mut implements = Vec::new();
308 if self.consume(TokenKind::KwImplements) {
309 loop {
310 if let Some(ty) = self.parse_type() {
311 implements.push(ty);
312 }
313 if !self.consume(TokenKind::Comma) {
314 break;
315 }
316 }
317 }
318
319 let mut permits = Vec::new();
321 if self.consume(TokenKind::KwPermits) {
322 loop {
323 if let Some(ty) = self.parse_type() {
324 permits.push(ty);
325 }
326 if !self.consume(TokenKind::Comma) {
327 break;
328 }
329 }
330 }
331
332 let old_in_interface = self.in_interface;
335 self.in_interface = matches!(kind, ClassKind::Interface);
336
337 self.expect(TokenKind::LBrace);
338 let members = self.parse_class_members(&name);
339 self.expect(TokenKind::RBrace);
340
341 self.in_interface = old_in_interface;
343
344 let class_decl = ClassDecl {
345 kind,
346 name,
347 type_params,
348 extends,
349 implements,
350 permits,
351 enum_entries: Vec::new(),
352 members,
353 modifiers,
354 };
355
356 Some(self.arena.alloc_class_decl(class_decl))
357 }
358
359 fn parse_type_params(&mut self) -> Vec<AstTypeParam> {
360 let mut params = Vec::new();
361 if !self.consume(TokenKind::Lt) {
362 return params;
363 }
364
365 loop {
366 if self.peek() == TokenKind::Ident {
367 let name = Ident::new(self.ident_text());
368 self.bump();
369
370 let mut bounds = Vec::new();
371 if self.consume(TokenKind::KwExtends) {
372 loop {
373 if let Some(ty) = self.parse_type() {
374 bounds.push(ty);
375 }
376 if !self.consume(TokenKind::Ampersand) {
377 break;
378 }
379 }
380 }
381
382 params.push(AstTypeParam {
383 name: name.name,
384 bounds,
385 });
386 }
387
388 if !self.consume(TokenKind::Comma) {
389 break;
390 }
391 }
392
393 self.expect(TokenKind::Gt);
394 params
395 }
396
397 fn parse_class_members(&mut self, class_name: &Ident) -> Vec<ClassMemberId> {
398 let mut members = Vec::new();
399
400 while !self.is(TokenKind::RBrace) && !self.is(TokenKind::Eof) {
401 if self.is(TokenKind::KwStatic) && self.peek() == TokenKind::LBrace {
403 self.bump();
404 if let Some(body) = self.parse_block() {
405 let member = ClassMember::StaticBlock(body);
406 members.push(self.arena.alloc_class_member(member));
407 }
408 continue;
409 }
410
411 let modifiers = self.parse_modifiers();
412
413 match self.peek() {
415 TokenKind::KwClass => {
416 self.bump();
417 if let Some(nested_id) =
418 self.parse_class_decl_inner(modifiers, ClassKind::Class)
419 {
420 let member = ClassMember::NestedClass(nested_id);
421 members.push(self.arena.alloc_class_member(member));
422 }
423 continue;
424 }
425 TokenKind::KwInterface => {
426 self.bump();
427 if let Some(nested_id) =
428 self.parse_class_decl_inner(modifiers, ClassKind::Interface)
429 {
430 let member = ClassMember::NestedInterface(nested_id);
431 members.push(self.arena.alloc_class_member(member));
432 }
433 continue;
434 }
435 TokenKind::KwEnum => {
436 self.bump();
437 if let Some(enum_id) = self.parse_enum_decl(modifiers) {
438 let member = ClassMember::NestedEnum(enum_id);
439 members.push(self.arena.alloc_class_member(member));
440 }
441 continue;
442 }
443 TokenKind::KwRecord => {
444 self.bump();
445 if let Some(record_id) =
446 self.parse_class_decl_inner(modifiers, ClassKind::Record)
447 {
448 let member = ClassMember::NestedRecord(record_id);
449 members.push(self.arena.alloc_class_member(member));
450 }
451 continue;
452 }
453 _ => {}
454 }
455
456 if let Some(ty) = self.parse_type() {
458 if self.is(TokenKind::LParen) && self.type_matches_constructor_name(ty, class_name)
459 {
460 if let Some(constructor) = self.parse_constructor(class_name.clone(), modifiers)
461 {
462 let member = ClassMember::Constructor(constructor);
463 members.push(self.arena.alloc_class_member(member));
464 }
465 continue;
466 }
467
468 if self.peek() == TokenKind::Ident {
469 let name = Ident::new(self.ident_text());
470 self.bump();
471
472 if self.is(TokenKind::LParen) {
473 if let Some(method_id) = self.parse_method(name, ty, modifiers) {
475 let member = ClassMember::Method(
476 self.arena.methods[method_id.0 as usize].clone(),
477 );
478 members.push(self.arena.alloc_class_member(member));
479 }
480 } else {
481 let initializer = if self.consume(TokenKind::Eq) {
483 self.parse_expression()
484 } else {
485 None
486 };
487
488 self.expect(TokenKind::Semi);
489
490 let field = Field {
491 name,
492 ty,
493 initializer,
494 modifiers,
495 };
496
497 let field_id = self.arena.alloc_field(field);
498 let member =
499 ClassMember::Field(self.arena.fields[field_id.0 as usize].clone());
500 members.push(self.arena.alloc_class_member(member));
501 }
502 }
503 } else if self.peek() == TokenKind::Ident {
504 let name = Ident::new(self.ident_text());
506 self.bump();
507 if let Some(constructor) = self.parse_constructor(name, modifiers) {
508 let member = ClassMember::Constructor(constructor);
509 members.push(self.arena.alloc_class_member(member));
510 }
511 } else {
512 self.bump();
513 }
514 }
515
516 members
517 }
518
519 fn parse_class_decl_inner(
520 &mut self,
521 modifiers: Modifiers,
522 kind: ClassKind,
523 ) -> Option<ClassDeclId> {
524 let name = if self.peek() == TokenKind::Ident {
525 Ident::new(self.ident_text())
526 } else {
527 return None;
528 };
529 self.bump();
530
531 let type_params = if self.is(TokenKind::Lt) {
532 self.parse_type_params()
533 } else {
534 Vec::new()
535 };
536
537 let extends = if self.consume(TokenKind::KwExtends) {
538 self.parse_type()
539 } else {
540 None
541 };
542
543 let mut implements = Vec::new();
544 if self.consume(TokenKind::KwImplements) {
545 loop {
546 if let Some(ty) = self.parse_type() {
547 implements.push(ty);
548 }
549 if !self.consume(TokenKind::Comma) {
550 break;
551 }
552 }
553 }
554
555 let old_in_interface = self.in_interface;
557 self.in_interface = matches!(kind, ClassKind::Interface);
558
559 self.expect(TokenKind::LBrace);
560 let members = self.parse_class_members(&name);
561 self.expect(TokenKind::RBrace);
562
563 self.in_interface = old_in_interface;
565
566 let class_decl = ClassDecl {
567 kind,
568 name,
569 type_params,
570 extends,
571 implements,
572 permits: Vec::new(),
573 enum_entries: Vec::new(),
574 members,
575 modifiers,
576 };
577
578 Some(self.arena.alloc_class_decl(class_decl))
579 }
580
581 fn parse_enum_decl(&mut self, modifiers: Modifiers) -> Option<ClassDeclId> {
582 let name = if self.peek() == TokenKind::Ident {
583 Ident::new(self.ident_text())
584 } else {
585 return None;
586 };
587 self.bump();
588 self.parse_enum_decl_with_name(name, modifiers)
589 }
590
591 fn parse_enum_decl_with_name(
592 &mut self,
593 name: Ident,
594 modifiers: Modifiers,
595 ) -> Option<ClassDeclId> {
596 let mut implements = Vec::new();
597 if self.consume(TokenKind::KwImplements) {
598 loop {
599 if let Some(ty) = self.parse_type() {
600 implements.push(ty);
601 }
602 if !self.consume(TokenKind::Comma) {
603 break;
604 }
605 }
606 }
607
608 self.expect(TokenKind::LBrace);
609
610 let mut entries = Vec::new();
611 while !self.is(TokenKind::RBrace) && !self.is(TokenKind::Eof) {
612 if self.peek() == TokenKind::Ident {
613 let entry_name = Ident::new(self.ident_text());
614 self.bump();
615
616 let args = if self.is(TokenKind::LParen) {
617 self.expect(TokenKind::LParen);
618 let mut args = Vec::new();
619 if !self.is(TokenKind::RParen) {
620 loop {
621 if let Some(arg) = self.parse_expression() {
622 args.push(arg);
623 }
624 if !self.consume(TokenKind::Comma) {
625 break;
626 }
627 }
628 }
629 self.expect(TokenKind::RParen);
630 args
631 } else {
632 Vec::new()
633 };
634
635 entries.push(EnumEntry {
636 name: entry_name,
637 args,
638 body: None,
639 });
640
641 if !self.consume(TokenKind::Comma) {
642 break;
643 }
644 } else {
645 break;
646 }
647 }
648
649 let mut members = Vec::new();
651 if self.consume(TokenKind::Semi) {
652 members = self.parse_class_members(&name);
653 }
654
655 self.expect(TokenKind::RBrace);
656
657 Some(self.arena.alloc_class_decl(ClassDecl {
658 kind: ClassKind::Enum,
659 name,
660 type_params: Vec::new(),
661 extends: None,
662 implements,
663 permits: Vec::new(),
664 enum_entries: entries,
665 members,
666 modifiers,
667 }))
668 }
669
670 fn parse_method(
671 &mut self,
672 name: Ident,
673 return_ty: AstTypeId,
674 modifiers: Modifiers,
675 ) -> Option<MethodId> {
676 self.expect(TokenKind::LParen);
677 let params = self.parse_parameters();
678 self.expect(TokenKind::RParen);
679
680 let mut throws = Vec::new();
681 if self.consume(TokenKind::KwThrows) {
682 loop {
683 if let Some(ty) = self.parse_type() {
684 throws.push(ty);
685 }
686 if !self.consume(TokenKind::Comma) {
687 break;
688 }
689 }
690 }
691
692 let body = if self.is(TokenKind::LBrace) {
693 self.parse_block()
694 } else {
695 self.consume(TokenKind::Semi);
696 None
697 };
698
699 let final_modifiers = if self.in_interface
701 && (modifiers.0
702 & (rajac_ast::Modifiers::PUBLIC
703 | rajac_ast::Modifiers::PRIVATE
704 | rajac_ast::Modifiers::PROTECTED))
705 == 0
706 {
707 Modifiers(modifiers.0 | rajac_ast::Modifiers::PUBLIC)
708 } else {
709 modifiers
710 };
711
712 let method = Method {
713 name,
714 params,
715 return_ty,
716 body,
717 throws,
718 modifiers: final_modifiers,
719 };
720
721 Some(self.arena.alloc_method(method))
722 }
723
724 fn parse_constructor(&mut self, name: Ident, modifiers: Modifiers) -> Option<Constructor> {
725 self.expect(TokenKind::LParen);
726 let params = self.parse_parameters();
727 self.expect(TokenKind::RParen);
728
729 let mut throws = Vec::new();
730 if self.consume(TokenKind::KwThrows) {
731 loop {
732 if let Some(ty) = self.parse_type() {
733 throws.push(ty);
734 }
735 if !self.consume(TokenKind::Comma) {
736 break;
737 }
738 }
739 }
740
741 let body = self.parse_block();
742
743 Some(Constructor {
744 name,
745 params,
746 body,
747 throws,
748 modifiers,
749 })
750 }
751
752 fn parse_parameters(&mut self) -> Vec<ParamId> {
753 let mut params = Vec::new();
754
755 if self.is(TokenKind::RParen) {
756 return params;
757 }
758
759 loop {
760 if let Some(ty) = self.parse_type() {
761 let varargs = self.consume(TokenKind::Dot)
762 && self.consume(TokenKind::Dot)
763 && self.consume(TokenKind::Dot);
764
765 if self.peek() == TokenKind::Ident {
766 let name = Ident::new(self.ident_text());
767 self.bump();
768
769 let param = Param { ty, name, varargs };
770 params.push(self.arena.alloc_param(param));
771 }
772 }
773
774 if !self.consume(TokenKind::Comma) {
775 break;
776 }
777 }
778
779 params
780 }
781
782 fn type_matches_constructor_name(&self, ty: AstTypeId, class_name: &Ident) -> bool {
783 matches!(
784 self.arena.ty(ty),
785 AstType::Simple { name, .. } if name == &class_name.name
786 )
787 }
788
789 pub fn parse_type(&mut self) -> Option<AstTypeId> {
790 self.parse_type_with_array_suffix(true)
791 }
792
793 pub fn parse_type_without_array_suffix(&mut self) -> Option<AstTypeId> {
794 self.parse_type_with_array_suffix(false)
795 }
796
797 fn parse_type_with_array_suffix(&mut self, allow_array_suffix: bool) -> Option<AstTypeId> {
798 let ty = match self.peek() {
799 TokenKind::KwBoolean => {
800 self.bump();
801 AstType::primitive(PrimitiveType::Boolean)
802 }
803 TokenKind::KwByte => {
804 self.bump();
805 AstType::primitive(PrimitiveType::Byte)
806 }
807 TokenKind::KwChar => {
808 self.bump();
809 AstType::primitive(PrimitiveType::Char)
810 }
811 TokenKind::KwShort => {
812 self.bump();
813 AstType::primitive(PrimitiveType::Short)
814 }
815 TokenKind::KwInt => {
816 self.bump();
817 AstType::primitive(PrimitiveType::Int)
818 }
819 TokenKind::KwLong => {
820 self.bump();
821 AstType::primitive(PrimitiveType::Long)
822 }
823 TokenKind::KwFloat => {
824 self.bump();
825 AstType::primitive(PrimitiveType::Float)
826 }
827 TokenKind::KwDouble => {
828 self.bump();
829 AstType::primitive(PrimitiveType::Double)
830 }
831 TokenKind::KwVoid => {
832 self.bump();
833 AstType::primitive(PrimitiveType::Void)
834 }
835 TokenKind::KwVar => {
836 self.bump();
837 AstType::primitive(PrimitiveType::Int)
839 }
840 TokenKind::Ident => {
841 let name = self.ident_text();
842 self.bump();
843
844 let type_args = if self.is(TokenKind::Lt) {
845 self.parse_type_arguments()
846 } else {
847 None
848 };
849
850 AstType::simple_with_args(name, type_args.unwrap_or_default())
851 }
852 TokenKind::Question => {
853 self.bump();
854 let bound = if self.consume(TokenKind::KwExtends) {
855 self.parse_type().map(WildcardBound::Extends)
856 } else if self.consume(TokenKind::KwSuper) {
857 self.parse_type().map(WildcardBound::Super)
858 } else {
859 None
860 };
861 AstType::wildcard(bound)
862 }
863 _ => return None,
864 };
865
866 let ty_id = self.arena.alloc_type(ty);
867
868 if !allow_array_suffix {
869 return Some(ty_id);
870 }
871
872 let mut dimensions = 0;
874 while self.consume(TokenKind::LBracket) {
875 self.expect(TokenKind::RBracket);
876 dimensions += 1;
877 }
878
879 if dimensions > 0 {
880 let array_type = AstType::array(ty_id, dimensions);
881 Some(self.arena.alloc_type(array_type))
882 } else {
883 Some(ty_id)
884 }
885 }
886
887 fn parse_type_arguments(&mut self) -> Option<Vec<AstTypeId>> {
888 if !self.consume(TokenKind::Lt) {
889 return None;
890 }
891
892 let mut args = Vec::new();
893 loop {
894 if self.peek() == TokenKind::Question {
895 self.bump();
896 let bound = if self.consume(TokenKind::KwExtends) {
897 self.parse_type().map(WildcardBound::Extends)
898 } else if self.consume(TokenKind::KwSuper) {
899 self.parse_type().map(WildcardBound::Super)
900 } else {
901 None
902 };
903 let wildcard = AstType::wildcard(bound);
904 args.push(self.arena.alloc_type(wildcard));
905 } else if let Some(ty) = self.parse_type() {
906 args.push(ty);
907 }
908
909 if !self.consume(TokenKind::Comma) {
910 break;
911 }
912 }
913
914 self.expect(TokenKind::Gt);
915 Some(args)
916 }
917}
918
919#[cfg(test)]
920mod tests {
921 use super::*;
922
923 fn parse_src(source: &str) -> ParseResult {
924 let lexer = Lexer::new(source, FilePath::new("test.java"));
925 let parser = Parser::new(lexer, source);
926 parser.parse_compilation_unit()
927 }
928
929 #[test]
930 fn test_empty_class() {
931 let result = parse_src("class HelloWorld {}");
932 assert_eq!(result.ast.classes.len(), 1);
933 }
934
935 #[test]
936 fn test_class_with_main_method() {
937 let source = r#"
938 public class HelloWorld {
939 public static void main(String[] args) {
940 }
941 }
942 "#;
943 let result = parse_src(source);
944 assert_eq!(result.ast.classes.len(), 1);
945 }
946
947 #[test]
948 fn test_package_and_import() {
949 let source = r#"
950 package com.example;
951 import java.util.List;
952 import static java.lang.Math.*;
953
954 class Example {}
955 "#;
956 let result = parse_src(source);
957 assert!(result.ast.package.is_some());
958 assert_eq!(result.ast.imports.len(), 2);
959 }
960
961 #[test]
962 fn test_field_declarations() {
963 let source = r#"
964 class Example {
965 private int x;
966 public static final String name = "test";
967 protected boolean flag;
968 }
969 "#;
970 let result = parse_src(source);
971 assert_eq!(result.ast.classes.len(), 1);
972 }
973
974 #[test]
975 fn test_method_declaration() {
976 let source = r#"
977 class Calculator {
978 public int add(int a, int b) {
979 return a + b;
980 }
981 }
982 "#;
983 let result = parse_src(source);
984 assert_eq!(result.ast.classes.len(), 1);
985 }
986
987 #[test]
988 fn test_return_new_array_expression() {
989 let source = r#"
990 class Arrays {
991 int[] make(int size) {
992 return new int[size];
993 }
994 }
995 "#;
996 let result = parse_src(source);
997 let class = result.arena.class_decl(result.ast.classes[0]);
998 let method = class
999 .members
1000 .iter()
1001 .find_map(|member_id| match result.arena.class_member(*member_id) {
1002 ClassMember::Method(method) => Some(method),
1003 _ => None,
1004 })
1005 .expect("method");
1006 let body_id = method.body.expect("method body");
1007 let Stmt::Block(statements) = result.arena.stmt(body_id) else {
1008 panic!("expected method body block");
1009 };
1010 let Stmt::Return(Some(expr_id)) = result.arena.stmt(statements[0]) else {
1011 panic!("expected return with expression");
1012 };
1013 let Expr::NewArray {
1014 dimensions,
1015 initializer,
1016 ..
1017 } = result.arena.expr(*expr_id)
1018 else {
1019 panic!("expected new array expression");
1020 };
1021 assert_eq!(dimensions.len(), 1);
1022 assert!(initializer.is_none());
1023 }
1024
1025 #[test]
1026 fn test_return_multidimensional_new_array_expression() {
1027 let source = r#"
1028 class Arrays {
1029 int[][] make(int rows, int cols) {
1030 return new int[rows][cols];
1031 }
1032 }
1033 "#;
1034 let result = parse_src(source);
1035 let class = result.arena.class_decl(result.ast.classes[0]);
1036 let method = class
1037 .members
1038 .iter()
1039 .find_map(|member_id| match result.arena.class_member(*member_id) {
1040 ClassMember::Method(method) => Some(method),
1041 _ => None,
1042 })
1043 .expect("method");
1044 let body_id = method.body.expect("method body");
1045 let Stmt::Block(statements) = result.arena.stmt(body_id) else {
1046 panic!("expected method body block");
1047 };
1048 let Stmt::Return(Some(expr_id)) = result.arena.stmt(statements[0]) else {
1049 panic!("expected return with expression");
1050 };
1051 let Expr::NewArray {
1052 dimensions,
1053 initializer,
1054 ..
1055 } = result.arena.expr(*expr_id)
1056 else {
1057 panic!("expected new array expression");
1058 };
1059 assert_eq!(dimensions.len(), 2);
1060 assert!(initializer.is_none());
1061 }
1062
1063 #[test]
1064 fn test_return_new_array_initializer_expression() {
1065 let source = r#"
1066 class Arrays {
1067 int[] make() {
1068 return new int[] { 1, 2, 3 };
1069 }
1070 }
1071 "#;
1072 let result = parse_src(source);
1073 let class = result.arena.class_decl(result.ast.classes[0]);
1074 let method = class
1075 .members
1076 .iter()
1077 .find_map(|member_id| match result.arena.class_member(*member_id) {
1078 ClassMember::Method(method) => Some(method),
1079 _ => None,
1080 })
1081 .expect("method");
1082 let body_id = method.body.expect("method body");
1083 let Stmt::Block(statements) = result.arena.stmt(body_id) else {
1084 panic!("expected method body block");
1085 };
1086 let Stmt::Return(Some(expr_id)) = result.arena.stmt(statements[0]) else {
1087 panic!("expected return with expression");
1088 };
1089 let Expr::NewArray {
1090 dimensions,
1091 initializer: Some(initializer),
1092 ..
1093 } = result.arena.expr(*expr_id)
1094 else {
1095 panic!("expected new array with initializer");
1096 };
1097 assert!(dimensions.is_empty());
1098 let Expr::ArrayInitializer { elements } = result.arena.expr(*initializer) else {
1099 panic!("expected array initializer");
1100 };
1101 assert_eq!(elements.len(), 3);
1102 }
1103
1104 #[test]
1105 fn test_return_nested_array_initializer_expression() {
1106 let source = r#"
1107 class Arrays {
1108 int[][] make() {
1109 return new int[][] { { 1 }, { 2, 3 } };
1110 }
1111 }
1112 "#;
1113 let result = parse_src(source);
1114 let class = result.arena.class_decl(result.ast.classes[0]);
1115 let method = class
1116 .members
1117 .iter()
1118 .find_map(|member_id| match result.arena.class_member(*member_id) {
1119 ClassMember::Method(method) => Some(method),
1120 _ => None,
1121 })
1122 .expect("method");
1123 let body_id = method.body.expect("method body");
1124 let Stmt::Block(statements) = result.arena.stmt(body_id) else {
1125 panic!("expected method body block");
1126 };
1127 let Stmt::Return(Some(expr_id)) = result.arena.stmt(statements[0]) else {
1128 panic!("expected return with expression");
1129 };
1130 let Expr::NewArray {
1131 initializer: Some(initializer),
1132 ..
1133 } = result.arena.expr(*expr_id)
1134 else {
1135 panic!("expected new array with initializer");
1136 };
1137 let Expr::ArrayInitializer { elements } = result.arena.expr(*initializer) else {
1138 panic!("expected outer array initializer");
1139 };
1140 assert_eq!(elements.len(), 2);
1141 assert!(matches!(
1142 result.arena.expr(elements[0]),
1143 Expr::ArrayInitializer { .. }
1144 ));
1145 }
1146
1147 #[test]
1148 fn test_constructor_declaration() {
1149 let source = r#"
1150 class Person {
1151 private String name;
1152
1153 public Person(String name) {
1154 this.name = name;
1155 }
1156 }
1157 "#;
1158 let result = parse_src(source);
1159 assert_eq!(result.ast.classes.len(), 1);
1160 let class = result.arena.class_decl(result.ast.classes[0]);
1161 assert!(class.members.iter().any(|member_id| matches!(
1162 result.arena.class_member(*member_id),
1163 ClassMember::Constructor(_)
1164 )));
1165 }
1166
1167 #[test]
1168 fn test_interface_declaration() {
1169 let source = r#"
1170 public interface Drawable {
1171 void draw();
1172 }
1173 "#;
1174 let result = parse_src(source);
1175 assert_eq!(result.ast.classes.len(), 1);
1176 }
1177
1178 #[test]
1179 fn test_enum_declaration() {
1180 let source = r#"
1181 public enum Color {
1182 RED, GREEN, BLUE
1183 }
1184 "#;
1185 let result = parse_src(source);
1186 assert_eq!(result.ast.classes.len(), 1);
1187 let class = result.arena.class_decl(result.ast.classes[0]);
1188 assert_eq!(class.kind, ClassKind::Enum);
1189 assert_eq!(class.enum_entries.len(), 3);
1190 assert_eq!(class.enum_entries[0].name.as_str(), "RED");
1191 }
1192
1193 #[test]
1194 fn test_generic_class() {
1195 let source = r#"
1196 public class Box<T> {
1197 private T content;
1198
1199 public T get() {
1200 return content;
1201 }
1202 }
1203 "#;
1204 let result = parse_src(source);
1205 assert_eq!(result.ast.classes.len(), 1);
1206 }
1207
1208 #[test]
1209 fn test_extends_and_implements() {
1210 let source = r#"
1211 public class ArrayList<E> extends AbstractList<E> implements List<E> {
1212 }
1213 "#;
1214 let result = parse_src(source);
1215 assert_eq!(result.ast.classes.len(), 1);
1216 }
1217
1218 #[test]
1219 fn test_expression_literals() {
1220 let source = r#"
1221 class Test {
1222 int a = 42;
1223 long b = 100L;
1224 float c = 3.14f;
1225 double d = 2.71828;
1226 String s = "hello";
1227 char ch = 'x';
1228 boolean flag = true;
1229 }
1230 "#;
1231 let result = parse_src(source);
1232 assert_eq!(result.ast.classes.len(), 1);
1233
1234 let class_decl = result.arena.class_decl(result.ast.classes[0]);
1235 let literal_kinds: Vec<_> = class_decl
1236 .members
1237 .iter()
1238 .filter_map(|member_id| match result.arena.class_member(*member_id) {
1239 ClassMember::Field(field) => {
1240 field
1241 .initializer
1242 .map(|expr_id| match result.arena.expr(expr_id) {
1243 Expr::Literal(literal) => literal.kind.clone(),
1244 _ => panic!("expected literal initializer"),
1245 })
1246 }
1247 _ => None,
1248 })
1249 .collect();
1250
1251 assert_eq!(
1252 literal_kinds,
1253 vec![
1254 LiteralKind::Int,
1255 LiteralKind::Long,
1256 LiteralKind::Float,
1257 LiteralKind::Double,
1258 LiteralKind::String,
1259 LiteralKind::Char,
1260 LiteralKind::Bool,
1261 ]
1262 );
1263 }
1264
1265 #[test]
1266 fn test_binary_operations() {
1267 let source = r#"
1268 class Calculator {
1269 void test() {
1270 int x = 5 + 3 * 2;
1271 int y = 10 - 4;
1272 int z = 8 / 2;
1273 boolean b = x > y && y < z;
1274 }
1275 }
1276 "#;
1277 let result = parse_src(source);
1278 assert_eq!(result.ast.classes.len(), 1);
1279 }
1280
1281 #[test]
1282 fn test_assignment_expression_statement() {
1283 let source = r#"
1284 class Test {
1285 void test() {
1286 int sum = 0;
1287 sum = sum + 1;
1288 }
1289 }
1290 "#;
1291 let result = parse_src(source);
1292 let class_decl = result.arena.class_decl(result.ast.classes[0]);
1293 let ClassMember::Method(method) = result.arena.class_member(class_decl.members[0]) else {
1294 panic!("expected method");
1295 };
1296 let body_id = method.body.expect("expected method body");
1297 let Stmt::Block(stmts) = result.arena.stmt(body_id) else {
1298 panic!("expected block body");
1299 };
1300 let Stmt::Expr(expr_id) = result.arena.stmt(stmts[1]) else {
1301 panic!("expected expression statement");
1302 };
1303
1304 assert!(matches!(result.arena.expr(*expr_id), Expr::Assign { .. }));
1305 }
1306
1307 #[test]
1308 fn test_if_statement() {
1309 let source = r#"
1310 class Test {
1311 void test() {
1312 if (x > 0) {
1313 x = x - 1;
1314 } else {
1315 x = 0;
1316 }
1317 }
1318 }
1319 "#;
1320 let result = parse_src(source);
1321 assert_eq!(result.ast.classes.len(), 1);
1322 }
1323
1324 #[test]
1325 fn test_loop_statements() {
1326 let source = r#"
1327 class Test {
1328 void test() {
1329 while (x > 0) {
1330 x--;
1331 }
1332
1333 do {
1334 y++;
1335 } while (y < 10);
1336
1337 for (int i = 0; i < 10; i++) {
1338 sum += i;
1339 }
1340 }
1341 }
1342 "#;
1343 let result = parse_src(source);
1344 assert_eq!(result.ast.classes.len(), 1);
1345 }
1346
1347 #[test]
1348 fn test_switch_statement() {
1349 let source = r#"
1350 class Test {
1351 void test(int day) {
1352 switch (day) {
1353 case 1:
1354 System.out.println("Monday");
1355 break;
1356 case 2:
1357 System.out.println("Tuesday");
1358 break;
1359 default:
1360 System.out.println("Other day");
1361 }
1362 }
1363 }
1364 "#;
1365 let result = parse_src(source);
1366 assert_eq!(result.ast.classes.len(), 1);
1367 }
1368
1369 #[test]
1370 fn test_labeled_statement() {
1371 let source = r#"
1372 class Test {
1373 void test(int limit) {
1374 outer: while (limit > 0) {
1375 limit--;
1376 continue outer;
1377 }
1378 }
1379 }
1380 "#;
1381 let result = parse_src(source);
1382 assert_eq!(result.ast.classes.len(), 1);
1383 }
1384
1385 #[test]
1386 fn test_try_catch() {
1387 let source = r#"
1388 class Test {
1389 void test() {
1390 try {
1391 int x = Integer.parseInt("123");
1392 } catch (NumberFormatException e) {
1393 System.out.println("Invalid number");
1394 } finally {
1395 System.out.println("Done");
1396 }
1397 }
1398 }
1399 "#;
1400 let result = parse_src(source);
1401 assert_eq!(result.ast.classes.len(), 1);
1402 }
1403
1404 #[test]
1405 fn test_method_calls() {
1406 let source = r#"
1407 class Test {
1408 void test() {
1409 String s = "hello";
1410 int len = s.length();
1411 System.out.println("Length: " + len);
1412 list.add(42);
1413 }
1414 }
1415 "#;
1416 let result = parse_src(source);
1417 assert_eq!(result.ast.classes.len(), 1);
1418 }
1419
1420 #[test]
1421 fn test_new_expression() {
1422 let source = r#"
1423 class Test {
1424 void test() {
1425 Object obj = new Object();
1426 List list = new ArrayList<>();
1427 int[] arr = new int[10];
1428 }
1429 }
1430 "#;
1431 let result = parse_src(source);
1432 assert_eq!(result.ast.classes.len(), 1);
1433 }
1434
1435 #[test]
1436 fn test_cast_expression() {
1437 let source = r#"
1438 class Test {
1439 void test() {
1440 Object obj = "string";
1441 String s = (String) obj;
1442 int x = (int) 3.14;
1443 }
1444 }
1445 "#;
1446 let result = parse_src(source);
1447 assert_eq!(result.ast.classes.len(), 1);
1448 }
1449
1450 #[test]
1451 fn test_ternary_expression() {
1452 let source = r#"
1453 class Test {
1454 void test() {
1455 int x = 5 > 3 ? 1 : 0;
1456 String msg = flag ? "yes" : "no";
1457 }
1458 }
1459 "#;
1460 let result = parse_src(source);
1461 assert_eq!(result.ast.classes.len(), 1);
1462 }
1463
1464 #[test]
1465 fn test_assignment_operators() {
1466 let source = r#"
1467 class Test {
1468 void test() {
1469 int x = 10;
1470 x += 5;
1471 x -= 3;
1472 x *= 2;
1473 x /= 4;
1474 x %= 3;
1475 }
1476 }
1477 "#;
1478 let result = parse_src(source);
1479 assert_eq!(result.ast.classes.len(), 1);
1480 }
1481
1482 #[test]
1483 fn test_nested_class() {
1484 let source = r#"
1485 public class Outer {
1486 public class Inner {
1487 void innerMethod() {}
1488 }
1489 }
1490 "#;
1491 let result = parse_src(source);
1492 assert_eq!(result.ast.classes.len(), 1);
1493 }
1494
1495 #[test]
1496 fn test_varargs_parameter() {
1497 let source = r#"
1498 class Test {
1499 void print(String... args) {
1500 for (String arg : args) {
1501 System.out.println(arg);
1502 }
1503 }
1504 }
1505 "#;
1506 let result = parse_src(source);
1507 assert_eq!(result.ast.classes.len(), 1);
1508 }
1509
1510 #[test]
1511 fn test_array_access() {
1512 let source = r#"
1513 class Test {
1514 void test() {
1515 int[] arr = {1, 2, 3};
1516 int first = arr[0];
1517 }
1518 }
1519 "#;
1520 let result = parse_src(source);
1521 assert_eq!(result.ast.classes.len(), 1);
1522 }
1523}