Skip to main content

java_lang/
parser.rs

1//! Parse implementations for all AST types.
2
3use crate::{
4    Result,
5    ast::*,
6    ident::Ident,
7    parse::{Parse, ParseStream},
8    span::Span,
9    token::TokenKind,
10};
11
12// ============================================================================
13// CompilationUnit
14// ============================================================================
15
16impl 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                // Drain any pending comments (they precede this semicolon)
26                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                // Try parsing package declaration (possibly with annotations)
34                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            // Collect doc comments before the declaration
47            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            // Type declaration
55            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        // Collect any remaining comments at the end of the file
61        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
84// ============================================================================
85// PackageDecl
86// ============================================================================
87
88impl 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
110// ============================================================================
111// ImportDecl
112// ============================================================================
113
114impl 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
171// ============================================================================
172// ModuleDecl
173// ============================================================================
174
175impl 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
320// ============================================================================
321// TypeDecl
322// ============================================================================
323
324impl 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                // Check for @interface (annotation type declaration)
348                let saved = input.cursor();
349                let at_span = input.peek().span;
350                input.next(); // consume '@'
351                if input.is(&TokenKind::Interface) {
352                    input.next(); // consume 'interface'
353                    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                // Otherwise it's an annotation before a type declaration
367                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
401// ============================================================================
402// Modifiers and Annotations
403// ============================================================================
404
405fn parse_annotations(input: &ParseStream) -> Result<Vec<Annotation>> {
406    let mut anns = Vec::new();
407    while input.is(&TokenKind::At) {
408        // Stop before @interface (annotation type declaration)
409        let saved = input.cursor();
410        input.next(); // consume '@'
411        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            // non-sealed is lexed as three tokens: Ident("non"), Minus, Sealed
459            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
503// ============================================================================
504// Annotation
505// ============================================================================
506
507impl 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            // Try to parse as Normal (key=value pairs)
523            // Check if first thing is ident followed by '=' or ','
524            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                        // Normal annotation
530                        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                        // It was just a value, backtrack
558                        input.set_cursor(saved);
559                    }
560                } else {
561                    input.set_cursor(saved);
562                }
563            }
564
565            // Single element annotation
566            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
648// ============================================================================
649// ClassDecl
650// ============================================================================
651
652fn 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            // Could be static initializer or static modifier for method/field
730            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            // Could be nested @interface
761            let saved = input.cursor();
762            let at_span = input.peek().span;
763            input.next(); // consume '@'
764            if input.is(&TokenKind::Interface) {
765                input.next(); // consume 'interface'
766                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    // Parse the return type (or constructor name)
793    let ty = parse_type(input)?;
794
795    if input.is(&TokenKind::LParen) {
796        // Constructor: ClassName(params) { ... }
797        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            // Method
829            input.expect(TokenKind::LParen)?;
830            let open = input.peek().span;
831            let params = parse_formal_params_after_lparen(input)?;
832            // Handle C-style array dimensions after params (e.g., int foo()[])
833            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        // Field
856        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        // Accept regular identifiers or `this` (for receiver parameters)
905        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        // Handle C-style array parameters: e.g. `char str[]` → treat as `char[] str`
913        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                // Merge with any existing array dims from the type
923                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
975// ============================================================================
976// InterfaceDecl
977// ============================================================================
978
979fn 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    // Check for @interface (annotation type)
1010    // body
1011    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            // Could be nested @interface
1066            let saved = input.cursor();
1067            let at_span = input.peek().span;
1068            input.next(); // consume '@'
1069            if input.is(&TokenKind::Interface) {
1070                input.next(); // consume 'interface'
1071                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            // Method
1103            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            // Constant field
1127            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
1171// ============================================================================
1172// EnumDecl
1173// ============================================================================
1174
1175fn 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
1258// ============================================================================
1259// RecordDecl
1260// ============================================================================
1261
1262fn 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    // Parse record components
1273    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    // Record body
1305    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    // Check for compact constructor: Name { ... }
1345    // A compact constructor has the same name as the record and no parameter list.
1346    // Lookahead: IDENT followed directly by `{` (not `(`)
1347    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                // Re-parse as field/method
1378                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        // Constructor: the parsed "type" is actually the constructor name (e.g., record name)
1471        // Extract the name from the type path
1472        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
1497/// Extract an identifier from a type that represents a constructor name.
1498/// The type must be a simple reference type with a single path segment (e.g., `Args`).
1499fn 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
1595// ============================================================================
1596// Path
1597// ============================================================================
1598
1599/// Parse a path for annotations - no type arguments allowed since annotations can't be parameterized
1600fn 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        // Speculative check: only consume the dot if followed by an identifier
1637        let saved = input.cursor();
1638        input.next(); // consume '.'
1639        // Consume any type-use annotations after . (e.g., OuterType.@Annotation InnerType)
1640        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
1669// ============================================================================
1670// Type
1671// ============================================================================
1672
1673fn 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        // Stop before @interface
1716        let saved = input.cursor();
1717        input.next(); // consume '@'
1718        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            // Nested @interface
1755            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        // Try class/interface/enum/record
1778        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        // Annotation element or field
1799        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            // Annotation element: Type name() [default value];
1805            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            // Field declaration: Type name [= value];
1829            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        // Check for annotations before [ (JSR 308 type-use annotations on array dimensions)
1911        // We need to be careful: annotations before [ should only be consumed if [ follows.
1912        let saved = input.cursor();
1913        let _pre_annotations = parse_type_annotations(input);
1914        if !input.is(&TokenKind::LBracket) {
1915            // No bracket found - restore cursor to before annotations
1916            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}
1941// Generics
1942// ============================================================================
1943
1944fn 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            // Consume any type-use annotations before the bound type
1963            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            // Split >> into one > for us and one > for the outer parser
2005            input.split_gt();
2006            gt_spans.push(input.peek().span);
2007            break;
2008        }
2009        if input.is(&TokenKind::GtGtGt) {
2010            // Split >>> into one > for us and two > for the outer parser
2011            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    // Handle diamond operator <>: empty type argument list
2036    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            // Split >> into one > for us and one > for the outer parser
2069            input.split_gt();
2070            gt_spans.push(input.peek().span);
2071            break;
2072        }
2073        if input.is(&TokenKind::GtGtGt) {
2074            // Split >>> into one > for us and two > for the outer parser
2075            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
2088// ============================================================================
2089// Statements
2090// ============================================================================
2091
2092fn 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    // Check for labeled statement: Ident ':'
2169    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    // Check for local class/interface/enum/record declaration
2191    // Also check for modifiers/annotations that may precede the type keyword
2192    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            // Only parse as local class if modifiers + keyword + ident pattern
2202            // e.g. "class Foo" or "abstract class Foo" but not "record.method()"
2203            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    // Check for local variable declaration or expression statement
2220    // Local var decl starts with type, possibly with var
2221    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    // Expression statement
2228    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            // Now check if next token is an identifier (local var decl) or something else
2258            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
2433/// Parse a case value expression, but don't allow `IDENTIFIER ->` to be parsed as a lambda.
2434fn parse_case_value(input: &ParseStream) -> Result<Expr> {
2435    // If we see IDENTIFIER followed by `->`, it's a case label arrow, not a lambda.
2436    // Check for this pattern before calling the full expression parser.
2437    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 we see `(` followed by a type and `)` then IDENTIFIER `->`, it's a cast case value
2442    // like `case (int) FOO ->`. The expression parser would treat `FOO ->` as a lambda
2443    // inside the cast, which is wrong — `->` here is the case arrow.
2444    // Detect this pattern by scanning ahead.
2445    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        // offset now points to matching `)`. Check what follows.
2464        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            // Parse as cast: (type) IDENTIFIER, leaving `->` for the switch parser.
2469            let open_span = input.peek().span;
2470            input.next(); // consume `(`
2471            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            // If the targeted parse failed, fall through to general expression parsing
2485        }
2486
2487        // Check for `(expr) ->` in switch case context.
2488        // This is a parenthesized case value followed by the arrow, NOT a lambda.
2489        // The expression parser would incorrectly parse this as a lambda.
2490        if matches!(after_rparen, TokenKind::Arrow) {
2491            // Parse as parenthesized expression, leaving `->` for the switch parser.
2492            let open_span = input.peek().span;
2493            input.next(); // consume `(`
2494            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                    // case null, default ->
2517                    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                // Java 21 pattern matching: case Type name -> or case Type(...) ->
2541                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                        // Add remaining values as a case
2564                        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
2590/// Check if the current position in a switch case is a pattern (Java 21+).
2591/// Patterns are: `Type name` (type pattern) or `Type(...)` (record pattern).
2592/// Returns false for simple constant values like `case FOO`.
2593fn is_case_pattern(input: &ParseStream) -> bool {
2594    // Must start with an identifier (the type)
2595    if !input.is_any_ident() {
2596        return false;
2597    }
2598    let next = input.look_ahead(1);
2599    match &next.kind {
2600        // Type pattern: `case Triangle t`
2601        TokenKind::Ident(_) => true,
2602        // Record pattern: `case Pair(...)`
2603        TokenKind::LParen => true,
2604        // Not a pattern: `case CONSTANT` or `case CONSTANT ->`
2605        _ => 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    // Check for enhanced for: Type ident : expr
2658    // Or regular for: init; cond; update
2659    let saved = input.cursor();
2660
2661    // Try enhanced for
2662    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    // Regular for
2668    let init = if input.is(&TokenKind::Semicolon) {
2669        input.next();
2670        ForInit::Exprs(Vec::new())
2671    } else {
2672        // Could be local var decl or expression list
2673        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()); // already advanced by parse_modifiers
2792        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        // Try-with-resources
2926        input.expect(TokenKind::LParen)?;
2927        let open = input.peek().span;
2928        let mut resources = Vec::new();
2929        loop {
2930            let saved = input.cursor();
2931            // Try parsing as a local var decl (without requiring semicolon)
2932            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
3067// ============================================================================
3068// Expressions (Pratt parser)
3069// ============================================================================
3070
3071fn 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            // Handle 'final' modifier in patterns (Java 16+)
3227            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                // Record pattern: instanceof Point(int x, int y)
3234                input.next(); // consume '('
3235                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                // Type pattern: instanceof String s
3254                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                    // Inner class creation: Outer.new InnerType(...)
3380                    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                        // Qualified super method call: Outer.super.method(args)
3440                        // Treat Outer.super as a special expression and continue parsing
3441                        // the .method() part in the next iteration
3442                        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                    // Inner class creation
3453                    continue;
3454                } else if input.is(&TokenKind::Lt) {
3455                    // Explicit type arguments: obj.<Type>method(args)
3456                    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                // Method call or cast
3486                // If current expr is a simple ident, it's a method call
3487                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                // Check if this was actually a cast: (Type) expr
3494                // Cast is handled in primary, so this is always a method call
3495                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                // Check for type arguments before the method call
3504                // Actually type args are before the name, e.g., name.<Type>method()
3505                // This should be handled differently...
3506
3507                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                // Check for empty brackets `[]` — could be array type suffix
3519                // before `.class` or `::` (e.g., `float[].class`, `String[]::new`)
3520                if input.is(&TokenKind::RBracket) {
3521                    input.next();
3522                    let close = input.peek().span;
3523                    // Collect more `[]` pairs
3524                    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                    // Now check if `.class` or `::` follows — if so, this is a type suffix
3539                    if input.is(&TokenKind::Dot) && input.look_ahead(1).kind == TokenKind::Class {
3540                        // Type suffix: convert expr to type, then handle .class
3541                        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(); // consume '.'
3550                        let class_span = input.peek().span;
3551                        input.next(); // consume 'class'
3552                        expr = Expr::ClassLit {
3553                            type_expr: Box::new(ty),
3554                            dot_span,
3555                            class_span,
3556                        };
3557                    } else if input.is(&TokenKind::ColonColon) {
3558                        // Method reference with array type: e.g., `ComponentName[]::new`
3559                        // Skip the `[]` — the `::` handler below will handle the rest
3560                        // The expression remains as the base identifier, which will be
3561                        // converted to a path by the `::` handler. Not perfect for array
3562                        // types but better than failing.
3563                        // Leave expr as-is (the base identifier)
3564                    } else {
3565                        // Standalone empty `[]` — probably a syntax error in context,
3566                        // but recover gracefully by treating as array type expression
3567                        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                    // Constructor reference
3607                    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    // Parenthesized expression, cast, or lambda
3695    if input.is(&TokenKind::LParen) {
3696        let open = span;
3697        input.next();
3698
3699        // Try to determine if this is a cast, lambda, or parenthesized expression
3700        let saved = input.cursor();
3701
3702        // Try parsing as type + ')' for cast
3703        if let Ok(ty) = parse_type(input) {
3704            // Handle intersection types: (Type & Type & ...) expr
3705            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                // Check if what follows ')' can start a cast operand (unary expression).
3716                // If not (e.g., '?', ')', ';'), this is likely a parenthesized expression, not a cast.
3717                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                    // Could be cast or lambda with typed params
3724                    // If next is '->', it's a lambda
3725                    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                    // For intersection types, we create a special cast expression
3745                    // For now, we just use the first type (could be enhanced later)
3746                    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        // Check for lambda: () -> ... or (params) -> ...
3758        // Cursor is at ')' (the first token after the consumed '(').
3759        // Scan forward: look_ahead(0) is ')', which matches our '('.
3760        {
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            // offset points to ')' position relative to current cursor
3780            // Check if token AFTER ')' is '->'
3781            if input.look_ahead(offset + 1).kind == TokenKind::Arrow {
3782                // Parse lambda params (cursor is after '('; parse_lambda_params_after_lparen
3783                // handles parsing until ')')
3784                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        // Parenthesized expression
3799        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            // Check for identifier (possibly with method reference)
3859            // Also allow primitive type keywords and void as identifiers for .class expressions
3860            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                // Check for single-param lambda: `x -> expr`
3867                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                // Check for type arguments followed by :: (method reference with type args)
3881                // e.g., Collection<T>::add, Class<?>[]::new
3882                if input.is(&TokenKind::Lt) {
3883                    let saved = input.save_state();
3884                    if let Ok(type_args) = parse_type_arguments(input) {
3885                        // Skip optional array dims [] between type args and ::
3886                        // e.g., Class<?>[]::new has [] between > and ::
3887                        while input.is(&TokenKind::LBracket)
3888                            && input.look_ahead(1).kind == TokenKind::RBracket
3889                        {
3890                            input.next(); // [
3891                            input.next(); // ]
3892                        }
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        // Try to parse as typed parameter: Type name
3937        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        // Parse as inferred parameter: just an ident
3955        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    // Parse the element/base type WITHOUT consuming array dimensions
4002    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    // Check for array creation: new Type[expr] or new Type[]
4020    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    // Class instantiation: new Type(args) or new Type { ... }
4063    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        // Anonymous class with no args
4097        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
4176// ============================================================================
4177// Pattern
4178// ============================================================================
4179
4180fn parse_pattern(input: &ParseStream) -> Result<Pattern> {
4181    let annotations = parse_annotations(input)?;
4182
4183    // Try record pattern: Type(Component1, Component2)
4184    // or type pattern: Type name
4185    let ty = parse_type(input)?;
4186
4187    if input.is(&TokenKind::LParen) {
4188        // Record pattern
4189        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        // Type pattern
4205        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}