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: MethodReturnType::Type(ty),
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: MethodReturnType::Type(ty),
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
1345    if input.is_any_ident() {
1346        let saved = input.cursor();
1347        let name = input.parse_ident().ok();
1348        if let Some(name) = name {
1349            if input.is(&TokenKind::LBrace) {
1350                let body = parse_constructor_body(input)?;
1351                return Ok(RecordBodyDecl::CompactConstructor(CompactConstructorDecl {
1352                    doc_comment,
1353                    modifiers,
1354                    name,
1355                    body,
1356                }));
1357            }
1358            input.set_cursor(saved);
1359        } else {
1360            input.set_cursor(saved);
1361        }
1362    }
1363
1364    match &input.peek().kind {
1365        TokenKind::LBrace => {
1366            let block = parse_block(input, Vec::new())?;
1367            Ok(RecordBodyDecl::InstanceInit(InstanceInit { block }))
1368        }
1369        TokenKind::Static => {
1370            let static_span = input.peek().span;
1371            input.next();
1372            if input.is(&TokenKind::LBrace) {
1373                let block = parse_block(input, Vec::new())?;
1374                Ok(RecordBodyDecl::StaticInit(StaticInit {
1375                    static_span,
1376                    block,
1377                }))
1378            } else {
1379                let mut rest_mods = modifiers;
1380                rest_mods.push(Modifier::Static(static_span));
1381                let rest = parse_modifiers(input);
1382                rest_mods.extend(rest);
1383                // Re-parse as field/method
1384                parse_record_body_decl_with_mods(input, doc_comment, rest_mods)
1385            }
1386        }
1387        TokenKind::Class => {
1388            let decl = parse_class_decl(input, doc_comment, modifiers)?;
1389            Ok(RecordBodyDecl::Class(decl))
1390        }
1391        TokenKind::Interface => {
1392            let decl = parse_interface_decl(input, doc_comment, modifiers)?;
1393            Ok(RecordBodyDecl::Interface(decl))
1394        }
1395        TokenKind::Enum => {
1396            let decl = parse_enum_decl(input, doc_comment, modifiers)?;
1397            Ok(RecordBodyDecl::Enum(decl))
1398        }
1399        TokenKind::Record => {
1400            let decl = parse_record_decl(input, doc_comment, modifiers)?;
1401            Ok(RecordBodyDecl::Record(decl))
1402        }
1403        _ => parse_record_body_decl_with_mods(input, doc_comment, modifiers),
1404    }
1405}
1406
1407fn parse_record_body_decl_with_mods(
1408    input: &ParseStream,
1409    doc_comment: Vec<Comment>,
1410    modifiers: Vec<Modifier>,
1411) -> Result<RecordBodyDecl> {
1412    let type_params = parse_optional_type_params(input);
1413    let ty = parse_type(input)?;
1414    if input.is_any_ident() {
1415        let name = input.parse_ident()?;
1416        if input.is(&TokenKind::LParen) {
1417            input.expect(TokenKind::LParen)?;
1418            let open = input.peek().span;
1419            let params = parse_formal_params_after_lparen(input)?;
1420            let throws_clause = parse_throws_clause(input)?;
1421            let body = if input.is(&TokenKind::LBrace) {
1422                Some(parse_block(input, Vec::new())?)
1423            } else {
1424                input.expect(TokenKind::Semicolon)?;
1425                None
1426            };
1427            return Ok(RecordBodyDecl::Method(MethodDecl {
1428                doc_comment,
1429                modifiers,
1430                type_params,
1431                return_type: MethodReturnType::Type(ty),
1432                name,
1433                receiver_param: None,
1434                params,
1435                paren_span: (open, input.peek().span),
1436                throws_clause,
1437                body,
1438            }));
1439        }
1440        let mut declarators = Vec::new();
1441        let dims = parse_array_dims(input)?;
1442        let initializer = if input.eat(&TokenKind::Eq) {
1443            Some(parse_expression(input)?)
1444        } else {
1445            None
1446        };
1447        declarators.push(VariableDeclarator {
1448            name: Some(name),
1449            dims,
1450            initializer,
1451        });
1452        while input.eat(&TokenKind::Comma) {
1453            let name = input.parse_ident()?;
1454            let dims = parse_array_dims(input)?;
1455            let initializer = if input.eat(&TokenKind::Eq) {
1456                Some(parse_expression(input)?)
1457            } else {
1458                None
1459            };
1460            declarators.push(VariableDeclarator {
1461                name: Some(name),
1462                dims,
1463                initializer,
1464            });
1465        }
1466        input.expect(TokenKind::Semicolon)?;
1467        let semi_span = input.peek().span;
1468        Ok(RecordBodyDecl::Field(FieldDecl {
1469            doc_comment,
1470            modifiers,
1471            ty,
1472            declarators,
1473            semi_span,
1474        }))
1475    } else {
1476        Err(crate::error::Error::new(
1477            input.peek().span,
1478            "expected record body member",
1479        ))
1480    }
1481}
1482
1483fn parse_constructor_body(input: &ParseStream) -> Result<ConstructorBody> {
1484    input.expect(TokenKind::LBrace)?;
1485    let open = input.peek().span;
1486    let mut explicit_constructor_call = None;
1487    let mut stmts = Vec::new();
1488
1489    if input.is(&TokenKind::This) || input.is(&TokenKind::Super) {
1490        let saved = input.cursor();
1491        let call = input.try_parse(parse_explicit_constructor_call);
1492        if let Some(call) = call {
1493            explicit_constructor_call = Some(call);
1494        } else {
1495            input.set_cursor(saved);
1496        }
1497    }
1498
1499    while !input.is_empty() {
1500        if input.is(&TokenKind::RBrace) {
1501            break;
1502        }
1503        stmts.push(parse_statement(input)?);
1504    }
1505    input.expect(TokenKind::RBrace)?;
1506    let close = input.peek().span;
1507    Ok(ConstructorBody {
1508        brace_span: (open, close),
1509        explicit_constructor_call,
1510        stmts,
1511    })
1512}
1513
1514fn parse_explicit_constructor_call(input: &ParseStream) -> Result<ExplicitConstructorCall> {
1515    let type_args = parse_optional_type_arguments(input);
1516    match &input.peek().kind {
1517        TokenKind::This => {
1518            let this_span = input.peek().span;
1519            input.next();
1520            input.expect(TokenKind::LParen)?;
1521            let open = input.peek().span;
1522            let args = input.parse_terminated(parse_expression)?;
1523            input.expect(TokenKind::RParen)?;
1524            let close = input.peek().span;
1525            input.expect(TokenKind::Semicolon)?;
1526            let semi_span = input.peek().span;
1527            Ok(ExplicitConstructorCall::This {
1528                type_args,
1529                this_span,
1530                paren_span: (open, close),
1531                args,
1532                semi_span,
1533            })
1534        }
1535        TokenKind::Super => {
1536            let super_span = input.peek().span;
1537            input.next();
1538            input.expect(TokenKind::LParen)?;
1539            let open = input.peek().span;
1540            let args = input.parse_terminated(parse_expression)?;
1541            input.expect(TokenKind::RParen)?;
1542            let close = input.peek().span;
1543            input.expect(TokenKind::Semicolon)?;
1544            let semi_span = input.peek().span;
1545            Ok(ExplicitConstructorCall::Super {
1546                type_args,
1547                super_span,
1548                paren_span: (open, close),
1549                args,
1550                semi_span,
1551            })
1552        }
1553        _ => Err(crate::error::Error::new(
1554            input.peek().span,
1555            "expected this or super",
1556        )),
1557    }
1558}
1559
1560// ============================================================================
1561// Path
1562// ============================================================================
1563
1564/// Parse a path for annotations - no type arguments allowed since annotations can't be parameterized
1565fn parse_annotation_path(input: &ParseStream) -> Result<Path> {
1566    let start = input.peek().span;
1567    let ident = input.parse_ident()?;
1568    let mut segments = vec![PathSegment { ident, args: None }];
1569
1570    while input.is(&TokenKind::Dot) {
1571        let saved = input.cursor();
1572        input.next();
1573        if input.is_any_ident() || is_contextual_type_keyword(&input.peek().kind) {
1574            let ident = input.parse_ident()?;
1575            segments.push(PathSegment { ident, args: None });
1576        } else {
1577            input.set_cursor(saved);
1578            break;
1579        }
1580    }
1581
1582    let end = if input.cursor() > 0 {
1583        input.look_ahead(0).span
1584    } else {
1585        start
1586    };
1587
1588    Ok(Path {
1589        segments,
1590        span: start.join(end),
1591    })
1592}
1593
1594fn parse_path(input: &ParseStream) -> Result<Path> {
1595    let start = input.peek().span;
1596    let ident = input.parse_ident()?;
1597    let args = parse_optional_type_arguments(input);
1598    let mut segments = vec![PathSegment { ident, args }];
1599
1600    while input.is(&TokenKind::Dot) {
1601        // Speculative check: only consume the dot if followed by an identifier
1602        let saved = input.cursor();
1603        input.next(); // consume '.'
1604        // Consume any type-use annotations after . (e.g., OuterType.@Annotation InnerType)
1605        let _annotations = parse_type_annotations(input);
1606        if input.is_any_ident() || is_contextual_type_keyword(&input.peek().kind) {
1607            let ident = input.parse_ident()?;
1608            let args = parse_optional_type_arguments(input);
1609            segments.push(PathSegment { ident, args });
1610        } else {
1611            input.set_cursor(saved);
1612            break;
1613        }
1614    }
1615
1616    let end = if input.cursor() > 0 {
1617        input.look_ahead(0).span
1618    } else {
1619        start
1620    };
1621    Ok(Path {
1622        segments,
1623        span: start.join(end),
1624    })
1625}
1626
1627fn is_contextual_type_keyword(kind: &TokenKind) -> bool {
1628    matches!(
1629        kind,
1630        TokenKind::Record | TokenKind::Sealed | TokenKind::Var | TokenKind::Yield | TokenKind::Open
1631    )
1632}
1633
1634// ============================================================================
1635// Type
1636// ============================================================================
1637
1638fn parse_type(input: &ParseStream) -> Result<Type> {
1639    let annotations = parse_type_annotations(input);
1640    let start = if let Some(ann) = annotations.first() {
1641        ann.span()
1642    } else {
1643        input.peek().span
1644    };
1645
1646    if input.is(&TokenKind::Void) {
1647        input.next();
1648        return Ok(Type::Void(input.peek().span));
1649    }
1650
1651    let base = if is_primitive_type_token(&input.peek().kind) {
1652        let prim = parse_primitive_type(input)?;
1653        Type::Primitive(prim)
1654    } else if input.is_any_ident() || is_contextual_type_keyword(&input.peek().kind) {
1655        let path = parse_path(input)?;
1656        Type::Reference(ReferenceType::ClassOrInterfaceType(ClassOrInterfaceType {
1657            path,
1658            annotations_prefix: annotations,
1659        }))
1660    } else {
1661        return Err(crate::error::Error::new(input.peek().span, "expected type"));
1662    };
1663
1664    let dims = parse_array_dims(input)?;
1665    if dims.is_empty() {
1666        Ok(base)
1667    } else {
1668        let span = start.join(dims.last().unwrap().bracket_span.1);
1669        Ok(Type::Reference(ReferenceType::Array(ArrayType {
1670            elem_type: Box::new(base),
1671            dims,
1672            span,
1673        })))
1674    }
1675}
1676
1677fn parse_type_annotations(input: &ParseStream) -> Vec<Annotation> {
1678    let mut anns = Vec::new();
1679    while input.is(&TokenKind::At) {
1680        // Stop before @interface
1681        let saved = input.cursor();
1682        input.next(); // consume '@'
1683        if input.is(&TokenKind::Interface) {
1684            input.set_cursor(saved);
1685            break;
1686        }
1687        input.set_cursor(saved);
1688        if let Some(ann) = input.try_parse(|i| i.parse::<Annotation>()) {
1689            anns.push(ann);
1690        } else {
1691            break;
1692        }
1693    }
1694    anns
1695}
1696
1697fn parse_annotation_type_body(input: &ParseStream) -> Result<AnnotationInterfaceBody> {
1698    input.expect(TokenKind::LBrace)?;
1699    let open = input.peek().span;
1700    let mut members = Vec::new();
1701    while !input.is_empty() {
1702        if input.is(&TokenKind::RBrace) {
1703            break;
1704        }
1705        if input.eat(&TokenKind::Semicolon) {
1706            members.push(AnnotationInterfaceMember::Empty(input.peek().span));
1707            continue;
1708        }
1709        let doc_comment = input.collect_pending_doc_comments();
1710        let modifiers = parse_modifiers(input);
1711        let annotations = parse_annotations(input)?;
1712        let mut all_mods: Vec<Modifier> = annotations
1713            .iter()
1714            .map(|a| Modifier::Annotation(a.clone()))
1715            .collect();
1716        all_mods.extend(modifiers);
1717
1718        if input.is(&TokenKind::At) {
1719            // Nested @interface
1720            let saved = input.cursor();
1721            let at_span = input.peek().span;
1722            input.next();
1723            if input.is(&TokenKind::Interface) {
1724                input.next();
1725                let name = input.parse_ident()?;
1726                let body = parse_annotation_type_body(input)?;
1727                members.push(AnnotationInterfaceMember::AnnotationInterface(
1728                    AnnotationInterfaceDecl {
1729                        doc_comment,
1730                        modifiers: all_mods,
1731                        at_span,
1732                        interface_span: name.span(),
1733                        name,
1734                        body,
1735                    },
1736                ));
1737                continue;
1738            }
1739            input.set_cursor(saved);
1740        }
1741
1742        // Try class/interface/enum/record
1743        if input.is(&TokenKind::Class) {
1744            let decl = parse_class_decl(input, doc_comment, all_mods)?;
1745            members.push(AnnotationInterfaceMember::Class(decl));
1746            continue;
1747        }
1748        if input.is(&TokenKind::Interface) {
1749            let decl = parse_interface_decl(input, doc_comment, all_mods)?;
1750            members.push(AnnotationInterfaceMember::Interface(decl));
1751            continue;
1752        }
1753        if input.is(&TokenKind::Enum) {
1754            let decl = parse_enum_decl(input, doc_comment, all_mods)?;
1755            members.push(AnnotationInterfaceMember::Enum(decl));
1756            continue;
1757        }
1758        if input.is(&TokenKind::Record) {
1759            let decl: RecordDecl = parse_record_decl(input, doc_comment, all_mods)?;
1760            members.push(AnnotationInterfaceMember::Record(decl));
1761            continue;
1762        }
1763        // Annotation element or field
1764        let ty = parse_type(input)?;
1765        let dims = parse_array_dims(input)?;
1766        let name = input.parse_ident()?;
1767
1768        if input.is(&TokenKind::LParen) {
1769            // Annotation element: Type name() [default value];
1770            let open_paren = input.peek().span;
1771            input.next();
1772            input.expect(TokenKind::RParen)?;
1773            let close_paren = input.peek().span;
1774            let default_value = if input.eat(&TokenKind::Default) {
1775                let eq_span = input.peek().span;
1776                let val = parse_element_value(input)?;
1777                Some((eq_span, val))
1778            } else {
1779                None
1780            };
1781            input.expect(TokenKind::Semicolon)?;
1782            let semi_span = input.peek().span;
1783            members.push(AnnotationInterfaceMember::Element(AnnotationElement {
1784                modifiers: all_mods,
1785                ty,
1786                name,
1787                paren_span: (open_paren, close_paren),
1788                dims,
1789                default_value,
1790                semi_span,
1791            }));
1792        } else {
1793            // Field declaration: Type name [= value];
1794            let mut declarators = Vec::new();
1795            let initializer = if input.eat(&TokenKind::Eq) {
1796                Some(parse_expression(input)?)
1797            } else {
1798                None
1799            };
1800            declarators.push(VariableDeclarator {
1801                name: Some(name),
1802                dims,
1803                initializer,
1804            });
1805            while input.eat(&TokenKind::Comma) {
1806                let name = input.parse_ident()?;
1807                let dims = parse_array_dims(input)?;
1808                let initializer = if input.eat(&TokenKind::Eq) {
1809                    Some(parse_expression(input)?)
1810                } else {
1811                    None
1812                };
1813                declarators.push(VariableDeclarator {
1814                    name: Some(name),
1815                    dims,
1816                    initializer,
1817                });
1818            }
1819            input.expect(TokenKind::Semicolon)?;
1820            let semi_span = input.peek().span;
1821            members.push(AnnotationInterfaceMember::Field(FieldDecl {
1822                doc_comment,
1823                modifiers: all_mods,
1824                ty,
1825                declarators,
1826                semi_span,
1827            }));
1828        }
1829    }
1830    input.expect(TokenKind::RBrace)?;
1831    let close = input.peek().span;
1832    Ok(AnnotationInterfaceBody {
1833        brace_span: (open, close),
1834        members,
1835    })
1836}
1837
1838fn is_primitive_type_token(kind: &TokenKind) -> bool {
1839    matches!(
1840        kind,
1841        TokenKind::Byte
1842            | TokenKind::Short
1843            | TokenKind::Int
1844            | TokenKind::Long
1845            | TokenKind::Char
1846            | TokenKind::Float
1847            | TokenKind::Double
1848            | TokenKind::Boolean
1849    )
1850}
1851
1852fn parse_primitive_type(input: &ParseStream) -> Result<PrimitiveType> {
1853    let prim = match &input.peek().kind {
1854        TokenKind::Byte => PrimitiveType::Byte,
1855        TokenKind::Short => PrimitiveType::Short,
1856        TokenKind::Int => PrimitiveType::Int,
1857        TokenKind::Long => PrimitiveType::Long,
1858        TokenKind::Char => PrimitiveType::Char,
1859        TokenKind::Float => PrimitiveType::Float,
1860        TokenKind::Double => PrimitiveType::Double,
1861        TokenKind::Boolean => PrimitiveType::Boolean,
1862        _ => {
1863            return Err(crate::error::Error::new(
1864                input.peek().span,
1865                "expected primitive type",
1866            ));
1867        }
1868    };
1869    input.next();
1870    Ok(prim)
1871}
1872fn parse_array_dims(input: &ParseStream) -> Result<Vec<ArrayDim>> {
1873    let mut dims = Vec::new();
1874    loop {
1875        // Check for annotations before [ (JSR 308 type-use annotations on array dimensions)
1876        // We need to be careful: annotations before [ should only be consumed if [ follows.
1877        let saved = input.cursor();
1878        let _pre_annotations = parse_type_annotations(input);
1879        if !input.is(&TokenKind::LBracket) {
1880            // No bracket found - restore cursor to before annotations
1881            input.set_cursor(saved);
1882            break;
1883        }
1884        let open = input.peek().span;
1885        input.next();
1886        let annotations = parse_type_annotations(input);
1887        input.expect(TokenKind::RBracket)?;
1888        let close = input.peek().span;
1889        dims.push(ArrayDim {
1890            bracket_span: (open, close),
1891            annotations,
1892        });
1893    }
1894    Ok(dims)
1895}
1896fn parse_type_list(input: &ParseStream) -> Vec<Type> {
1897    let mut types = Vec::new();
1898    while let Ok(ty) = parse_type(input) {
1899        types.push(ty);
1900        if !input.eat(&TokenKind::Comma) {
1901            break;
1902        }
1903    }
1904    types
1905}
1906// Generics
1907// ============================================================================
1908
1909fn parse_optional_type_params(input: &ParseStream) -> Option<TypeParameters> {
1910    if input.is(&TokenKind::Lt) {
1911        parse_type_params(input).ok()
1912    } else {
1913        None
1914    }
1915}
1916
1917fn parse_type_params(input: &ParseStream) -> Result<TypeParameters> {
1918    let lt_span = input.peek().span;
1919    input.expect(TokenKind::Lt)?;
1920    let mut gt_spans = Vec::new();
1921    let mut params = Vec::new();
1922    loop {
1923        let annotations = parse_annotations(input)?;
1924        let name = input.parse_ident()?;
1925        let bound = if input.eat(&TokenKind::Extends) {
1926            let extends_span = input.peek().span;
1927            // Consume any type-use annotations before the bound type
1928            let _annotations = parse_type_annotations(input);
1929            let first = parse_path(input)?;
1930            let mut additional = Vec::new();
1931            while input.eat(&TokenKind::Amp) {
1932                let _annotations = parse_type_annotations(input);
1933                additional.push(parse_path(input)?);
1934            }
1935            Some(TypeBound {
1936                first,
1937                additional,
1938                extends_span,
1939            })
1940        } else {
1941            None
1942        };
1943        let span = annotations
1944            .first()
1945            .map(|a| a.span())
1946            .unwrap_or(name.span())
1947            .join(
1948                bound
1949                    .as_ref()
1950                    .map(|b| {
1951                        b.additional
1952                            .last()
1953                            .map(|p| p.span)
1954                            .unwrap_or_else(|| b.first.span)
1955                    })
1956                    .unwrap_or(name.span()),
1957            );
1958        params.push(TypeParameter {
1959            annotations,
1960            name,
1961            bound,
1962            span,
1963        });
1964        if input.eat(&TokenKind::Gt) {
1965            gt_spans.push(input.peek().span);
1966            break;
1967        }
1968        if input.is(&TokenKind::GtGt) {
1969            // Split >> into one > for us and one > for the outer parser
1970            input.split_gt();
1971            gt_spans.push(input.peek().span);
1972            break;
1973        }
1974        if input.is(&TokenKind::GtGtGt) {
1975            // Split >>> into one > for us and two > for the outer parser
1976            input.split_gt();
1977            gt_spans.push(input.peek().span);
1978            break;
1979        }
1980        input.expect(TokenKind::Comma)?;
1981    }
1982    Ok(TypeParameters {
1983        params,
1984        lt_span,
1985        gt_spans,
1986    })
1987}
1988
1989fn parse_optional_type_arguments(input: &ParseStream) -> Option<TypeArguments> {
1990    if input.is(&TokenKind::Lt) {
1991        parse_type_arguments(input).ok()
1992    } else {
1993        None
1994    }
1995}
1996
1997fn parse_type_arguments(input: &ParseStream) -> Result<TypeArguments> {
1998    let lt_span = input.peek().span;
1999    input.expect(TokenKind::Lt)?;
2000    // Handle diamond operator <>: empty type argument list
2001    if input.eat(&TokenKind::Gt) {
2002        let gt_spans = vec![input.peek().span];
2003        return Ok(TypeArguments {
2004            args: vec![],
2005            lt_token: lt_span,
2006            gt_tokens: gt_spans,
2007        });
2008    }
2009    let mut gt_spans = Vec::new();
2010    let mut args = Vec::new();
2011    loop {
2012        if input.eat(&TokenKind::Question) {
2013            let wildcard_span = input.peek().span;
2014            let bound = if input.eat(&TokenKind::Extends) {
2015                Some(WildcardBound::Extends(Box::new(parse_type(input)?)))
2016            } else if input.eat(&TokenKind::Super) {
2017                Some(WildcardBound::Super(Box::new(parse_type(input)?)))
2018            } else {
2019                None
2020            };
2021            args.push(TypeArgument::Wildcard(Wildcard {
2022                bound,
2023                span: wildcard_span,
2024            }));
2025        } else {
2026            args.push(TypeArgument::Type(Box::new(parse_type(input)?)));
2027        }
2028        if input.eat(&TokenKind::Gt) {
2029            gt_spans.push(input.peek().span);
2030            break;
2031        }
2032        if input.is(&TokenKind::GtGt) {
2033            // Split >> into one > for us and one > for the outer parser
2034            input.split_gt();
2035            gt_spans.push(input.peek().span);
2036            break;
2037        }
2038        if input.is(&TokenKind::GtGtGt) {
2039            // Split >>> into one > for us and two > for the outer parser
2040            input.split_gt();
2041            gt_spans.push(input.peek().span);
2042            break;
2043        }
2044        input.expect(TokenKind::Comma)?;
2045    }
2046    Ok(TypeArguments {
2047        args,
2048        lt_token: lt_span,
2049        gt_tokens: gt_spans,
2050    })
2051}
2052
2053// ============================================================================
2054// Statements
2055// ============================================================================
2056
2057fn parse_block(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Block> {
2058    let open = input.peek().span;
2059    input.expect(TokenKind::LBrace)?;
2060    let mut stmts = Vec::new();
2061    while !input.is_empty() {
2062        if input.is(&TokenKind::RBrace) {
2063            break;
2064        }
2065        stmts.push(parse_statement(input)?);
2066    }
2067    input.expect(TokenKind::RBrace)?;
2068    let close = input.peek().span;
2069    Ok(Block {
2070        leading_comments,
2071        brace_span: (open, close),
2072        stmts,
2073    })
2074}
2075
2076fn parse_statement(input: &ParseStream) -> Result<Stmt> {
2077    let leading_comments = input.collect_pending_comments();
2078    parse_statement_with_comments(input, leading_comments)
2079}
2080
2081fn parse_statement_with_comments(
2082    input: &ParseStream,
2083    leading_comments: Vec<Comment>,
2084) -> Result<Stmt> {
2085    if input.is(&TokenKind::LBrace) {
2086        let block = parse_block(input, leading_comments)?;
2087        return Ok(Stmt::Block(block));
2088    }
2089    if input.is(&TokenKind::Semicolon) {
2090        let sp = input.next().span;
2091        return Ok(Stmt::Empty(sp));
2092    }
2093    if input.is(&TokenKind::If) {
2094        return parse_if_stmt(input, leading_comments);
2095    }
2096    if input.is(&TokenKind::Assert) {
2097        return parse_assert_stmt(input, leading_comments);
2098    }
2099    if input.is(&TokenKind::Switch) {
2100        return parse_switch_stmt(input, leading_comments);
2101    }
2102    if input.is(&TokenKind::While) {
2103        return parse_while_stmt(input, leading_comments);
2104    }
2105    if input.is(&TokenKind::Do) {
2106        return parse_do_while_stmt(input, leading_comments);
2107    }
2108    if input.is(&TokenKind::For) {
2109        return parse_for_stmt(input, leading_comments);
2110    }
2111    if input.is(&TokenKind::Break) {
2112        return parse_jump_stmt(input, TokenKind::Break, Stmt::Break, leading_comments);
2113    }
2114    if input.is(&TokenKind::Continue) {
2115        return parse_jump_stmt(input, TokenKind::Continue, Stmt::Continue, leading_comments);
2116    }
2117    if input.is(&TokenKind::Return) {
2118        return parse_return_stmt(input, leading_comments);
2119    }
2120    if input.is(&TokenKind::Throw) {
2121        return parse_throw_stmt(input, leading_comments);
2122    }
2123    if input.is(&TokenKind::Synchronized) {
2124        return parse_synchronized_stmt(input, leading_comments);
2125    }
2126    if input.is(&TokenKind::Try) {
2127        return parse_try_stmt(input, leading_comments);
2128    }
2129    if input.is(&TokenKind::Yield) {
2130        return parse_yield_stmt(input, leading_comments);
2131    }
2132
2133    // Check for labeled statement: Ident ':'
2134    if input.is_any_ident() {
2135        let saved = input.cursor();
2136        let ident = input.parse_ident().ok();
2137        if let Some(ident) = ident {
2138            if input.is(&TokenKind::Colon) {
2139                let colon_span = input.peek().span;
2140                input.next();
2141                let stmt = parse_statement(input)?;
2142                return Ok(Stmt::Labeled(LabeledStmt {
2143                    leading_comments,
2144                    label: ident,
2145                    colon_span,
2146                    stmt: Box::new(stmt),
2147                }));
2148            }
2149            input.set_cursor(saved);
2150        } else {
2151            input.set_cursor(saved);
2152        }
2153    }
2154
2155    // Check for local class/interface/enum/record declaration
2156    // Also check for modifiers/annotations that may precede the type keyword
2157    if input.is(&TokenKind::Class)
2158        || input.is(&TokenKind::Interface)
2159        || input.is(&TokenKind::Enum)
2160        || input.is(&TokenKind::Record)
2161        || input.is(&TokenKind::At)
2162        || is_modifier_keyword(&input.peek().kind)
2163    {
2164        let saved = input.cursor();
2165        match input.try_parse(|i| {
2166            // Only parse as local class if modifiers + keyword + ident pattern
2167            // e.g. "class Foo" or "abstract class Foo" but not "record.method()"
2168            let _modifiers = parse_modifiers(i);
2169            if !matches!(
2170                i.peek().kind,
2171                TokenKind::Class | TokenKind::Interface | TokenKind::Enum | TokenKind::Record
2172            ) {
2173                return Err(crate::error::Error::new(i.peek().span, "not a local class"));
2174            }
2175            TypeDecl::parse(i)
2176        }) {
2177            Some(decl) => return Ok(Stmt::ClassDecl(Box::new(decl))),
2178            None => {
2179                input.set_cursor(saved);
2180            }
2181        }
2182    }
2183
2184    // Check for local variable declaration or expression statement
2185    // Local var decl starts with type, possibly with var
2186    let saved = input.cursor();
2187    if let Some(stmt) = try_parse_local_var_decl_or_expr_stmt(input, leading_comments.clone()) {
2188        return Ok(stmt);
2189    }
2190    input.set_cursor(saved);
2191
2192    // Expression statement
2193    let expr = parse_expression(input)?;
2194    input.expect(TokenKind::Semicolon)?;
2195    let semi_span = input.peek().span;
2196    Ok(Stmt::Expr(ExprStmt {
2197        leading_comments,
2198        expr,
2199        semi_span,
2200    }))
2201}
2202
2203fn try_parse_local_var_decl_or_expr_stmt(
2204    input: &ParseStream,
2205    leading_comments: Vec<Comment>,
2206) -> Option<Stmt> {
2207    let modifiers = parse_modifiers(input);
2208    let is_var = input.is(&TokenKind::Var);
2209    let can_start_type = crate::token::can_start_type(&input.peek().kind);
2210
2211    if is_var || can_start_type {
2212        let saved = input.cursor();
2213        let ty_result = if is_var {
2214            let var_span = input.peek().span;
2215            input.next();
2216            Ok(LocalVarType::Var(var_span))
2217        } else {
2218            parse_type(input).map(LocalVarType::Type)
2219        };
2220
2221        if let Ok(ty) = ty_result {
2222            // Now check if next token is an identifier (local var decl) or something else
2223            if input.is_any_ident() {
2224                let name = input.parse_ident().ok()?;
2225                let dims = parse_array_dims(input).ok().unwrap_or_default();
2226                let initializer = if input.eat(&TokenKind::Eq) {
2227                    parse_expression(input).ok()
2228                } else {
2229                    None
2230                };
2231                let mut declarators = vec![VariableDeclarator {
2232                    name: Some(name),
2233                    dims,
2234                    initializer,
2235                }];
2236                while input.eat(&TokenKind::Comma) {
2237                    let name = input.parse_ident().ok()?;
2238                    let dims = parse_array_dims(input).ok().unwrap_or_default();
2239                    let init = if input.eat(&TokenKind::Eq) {
2240                        parse_expression(input).ok()
2241                    } else {
2242                        None
2243                    };
2244                    declarators.push(VariableDeclarator {
2245                        name: Some(name),
2246                        dims,
2247                        initializer: init,
2248                    });
2249                }
2250                if input.eat(&TokenKind::Semicolon) {
2251                    let semi_span = input.peek().span;
2252                    return Some(Stmt::LocalVarDecl(LocalVarDeclStmt {
2253                        leading_comments,
2254                        modifiers,
2255                        ty,
2256                        declarators,
2257                        semi_span,
2258                    }));
2259                }
2260            }
2261        }
2262        input.set_cursor(saved);
2263    }
2264    None
2265}
2266
2267fn parse_if_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2268    let if_span = input.peek().span;
2269    input.expect(TokenKind::If)?;
2270    input.expect(TokenKind::LParen)?;
2271    let open = input.peek().span;
2272    let cond = parse_expression(input)?;
2273    input.expect(TokenKind::RParen)?;
2274    let close = input.peek().span;
2275    let then_stmt = parse_statement(input)?;
2276    let else_clause = if input.eat(&TokenKind::Else) {
2277        let else_span = input.peek().span;
2278        let else_stmt = parse_statement(input)?;
2279        Some((else_span, Box::new(else_stmt)))
2280    } else {
2281        None
2282    };
2283    Ok(Stmt::If(IfStmt {
2284        leading_comments,
2285        if_span,
2286        paren_span: (open, close),
2287        cond,
2288        then_stmt: Box::new(then_stmt),
2289        else_clause,
2290    }))
2291}
2292
2293fn parse_assert_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2294    let assert_span = input.peek().span;
2295    input.expect(TokenKind::Assert)?;
2296    let cond = parse_expression(input)?;
2297    let detail = if input.eat(&TokenKind::Colon) {
2298        let colon_span = input.peek().span;
2299        let detail = parse_expression(input)?;
2300        Some((colon_span, detail))
2301    } else {
2302        None
2303    };
2304    input.expect(TokenKind::Semicolon)?;
2305    let semi_span = input.peek().span;
2306    Ok(Stmt::Assert(AssertStmt {
2307        leading_comments,
2308        assert_span,
2309        cond,
2310        detail,
2311        semi_span,
2312    }))
2313}
2314
2315fn parse_switch_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2316    let switch_span = input.peek().span;
2317    input.expect(TokenKind::Switch)?;
2318    input.expect(TokenKind::LParen)?;
2319    let open = input.peek().span;
2320    let selector = parse_expression(input)?;
2321    input.expect(TokenKind::RParen)?;
2322    let close = input.peek().span;
2323    input.expect(TokenKind::LBrace)?;
2324    let brace_open = input.peek().span;
2325    let mut cases = Vec::new();
2326    while !input.is_empty() {
2327        if input.is(&TokenKind::RBrace) {
2328            break;
2329        }
2330        let labels = parse_switch_labels(input)?;
2331        let colon_span = if input.eat(&TokenKind::Colon) || input.eat(&TokenKind::Arrow) {
2332            input.peek().span
2333        } else {
2334            break;
2335        };
2336        let mut stmts = Vec::new();
2337        while !input.is_empty() {
2338            if is_switch_label_start(input) || input.is(&TokenKind::RBrace) {
2339                break;
2340            }
2341            stmts.push(parse_statement(input)?);
2342        }
2343        cases.push(SwitchCaseGroup {
2344            labels,
2345            colon_span,
2346            stmts,
2347        });
2348    }
2349    input.expect(TokenKind::RBrace)?;
2350    let brace_close = input.peek().span;
2351    Ok(Stmt::Switch(SwitchStmt {
2352        leading_comments,
2353        switch_span,
2354        paren_span: (open, close),
2355        selector,
2356        brace_span: (brace_open, brace_close),
2357        cases,
2358    }))
2359}
2360
2361fn is_any_ident_kind(kind: &TokenKind) -> bool {
2362    matches!(
2363        kind,
2364        TokenKind::Ident(_)
2365            | TokenKind::Record
2366            | TokenKind::Sealed
2367            | TokenKind::Var
2368            | TokenKind::Yield
2369            | TokenKind::Open
2370            | TokenKind::Provides
2371            | TokenKind::Requires
2372            | TokenKind::Uses
2373            | TokenKind::With
2374            | TokenKind::When
2375            | TokenKind::To
2376            | TokenKind::Exports
2377            | TokenKind::Opens
2378            | TokenKind::Transitive
2379            | TokenKind::Permits
2380            | TokenKind::NonSealed
2381            | TokenKind::Module
2382            | TokenKind::Byte
2383            | TokenKind::Short
2384            | TokenKind::Int
2385            | TokenKind::Long
2386            | TokenKind::Char
2387            | TokenKind::Float
2388            | TokenKind::Double
2389            | TokenKind::Boolean
2390            | TokenKind::Void
2391    )
2392}
2393
2394fn is_switch_label_start(input: &ParseStream) -> bool {
2395    input.is(&TokenKind::Case) || input.is(&TokenKind::Default)
2396}
2397
2398/// Parse a case value expression, but don't allow `IDENTIFIER ->` to be parsed as a lambda.
2399fn parse_case_value(input: &ParseStream) -> Result<Expr> {
2400    // If we see IDENTIFIER followed by `->`, it's a case label arrow, not a lambda.
2401    // Check for this pattern before calling the full expression parser.
2402    if input.is_any_ident() && input.look_ahead(1).kind == TokenKind::Arrow {
2403        let ident = input.parse_ident()?;
2404        return Ok(Expr::Ident(ident));
2405    }
2406    // If we see `(` followed by a type and `)` then IDENTIFIER `->`, it's a cast case value
2407    // like `case (int) FOO ->`. The expression parser would treat `FOO ->` as a lambda
2408    // inside the cast, which is wrong — `->` here is the case arrow.
2409    // Detect this pattern by scanning ahead.
2410    if input.is(&TokenKind::LParen) {
2411        let mut depth = 1usize;
2412        let mut offset = 1usize;
2413        loop {
2414            let tok = input.look_ahead(offset);
2415            match &tok.kind {
2416                TokenKind::LParen => depth += 1,
2417                TokenKind::RParen => {
2418                    depth -= 1;
2419                    if depth == 0 {
2420                        break;
2421                    }
2422                }
2423                TokenKind::Eof => break,
2424                _ => {}
2425            }
2426            offset += 1;
2427        }
2428        // offset now points to matching `)`. Check if `IDENTIFIER ->` follows.
2429        let after_rparen = &input.look_ahead(offset + 1).kind;
2430        let after_that = &input.look_ahead(offset + 2).kind;
2431        if is_any_ident_kind(after_rparen) && matches!(after_that, TokenKind::Arrow) {
2432            // Parse as cast: (type) IDENTIFIER, leaving `->` for the switch parser.
2433            let open_span = input.peek().span;
2434            input.next(); // consume `(`
2435            let saved = input.cursor();
2436            if let Ok(ty) = parse_type(input)
2437                && input.eat(&TokenKind::RParen)
2438            {
2439                let close_span = input.peek().span;
2440                let ident = input.parse_ident()?;
2441                return Ok(Expr::Cast(CastExpr {
2442                    paren_span: (open_span, close_span),
2443                    target_type: ty,
2444                    expr: Box::new(Expr::Ident(ident)),
2445                }));
2446            }
2447            input.set_cursor(saved);
2448            // If the targeted parse failed, fall through to general expression parsing
2449        }
2450    }
2451    parse_expression(input)
2452}
2453
2454fn parse_switch_labels(input: &ParseStream) -> Result<Vec<SwitchCase>> {
2455    let mut labels = Vec::new();
2456    loop {
2457        if input.is(&TokenKind::Case) {
2458            let case_span = input.peek().span;
2459            input.next();
2460            if input.is(&TokenKind::NullLit) {
2461                let null_span = input.peek().span;
2462                input.next();
2463                if input.eat(&TokenKind::Comma) {
2464                    // case null, default ->
2465                    if input.is(&TokenKind::Default) {
2466                        let default_span = input.peek().span;
2467                        input.next();
2468                        labels.push(SwitchCase::CaseNullDefault {
2469                            case_span,
2470                            null_span,
2471                            default_span,
2472                        });
2473                        break;
2474                    }
2475                } else {
2476                    labels.push(SwitchCase::CaseNull {
2477                        case_span,
2478                        null_span,
2479                    });
2480                    break;
2481                }
2482            } else if input.is(&TokenKind::Default) {
2483                let default_span = input.peek().span;
2484                input.next();
2485                labels.push(SwitchCase::Default { default_span });
2486                break;
2487            } else {
2488                let mut values = Vec::new();
2489                values.push(parse_case_value(input)?);
2490                while input.eat(&TokenKind::Comma) {
2491                    if input.is(&TokenKind::Default) {
2492                        let default_span = input.peek().span;
2493                        input.next();
2494                        // Add remaining values as a case
2495                        labels.push(SwitchCase::CaseValues {
2496                            case_span,
2497                            values: std::mem::take(&mut values),
2498                        });
2499                        labels.push(SwitchCase::Default { default_span });
2500                        break;
2501                    }
2502                    values.push(parse_case_value(input)?);
2503                }
2504                if !values.is_empty() {
2505                    labels.push(SwitchCase::CaseValues { case_span, values });
2506                }
2507                break;
2508            }
2509        } else if input.is(&TokenKind::Default) {
2510            let default_span = input.peek().span;
2511            input.next();
2512            labels.push(SwitchCase::Default { default_span });
2513            break;
2514        } else {
2515            break;
2516        }
2517    }
2518    Ok(labels)
2519}
2520
2521fn parse_while_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2522    let while_span = input.peek().span;
2523    input.expect(TokenKind::While)?;
2524    input.expect(TokenKind::LParen)?;
2525    let open = input.peek().span;
2526    let cond = parse_expression(input)?;
2527    input.expect(TokenKind::RParen)?;
2528    let close = input.peek().span;
2529    let body = parse_statement(input)?;
2530    Ok(Stmt::While(WhileStmt {
2531        leading_comments,
2532        while_span,
2533        paren_span: (open, close),
2534        cond,
2535        body: Box::new(body),
2536    }))
2537}
2538
2539fn parse_do_while_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2540    let do_span = input.peek().span;
2541    input.expect(TokenKind::Do)?;
2542    let body = parse_statement(input)?;
2543    let while_span = input.peek().span;
2544    input.expect(TokenKind::While)?;
2545    input.expect(TokenKind::LParen)?;
2546    let open = input.peek().span;
2547    let cond = parse_expression(input)?;
2548    input.expect(TokenKind::RParen)?;
2549    let close = input.peek().span;
2550    input.expect(TokenKind::Semicolon)?;
2551    let semi_span = input.peek().span;
2552    Ok(Stmt::DoWhile(DoWhileStmt {
2553        leading_comments,
2554        do_span,
2555        body: Box::new(body),
2556        while_span,
2557        paren_span: (open, close),
2558        cond,
2559        semi_span,
2560    }))
2561}
2562
2563fn parse_for_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2564    let for_span = input.peek().span;
2565    input.expect(TokenKind::For)?;
2566    input.expect(TokenKind::LParen)?;
2567    let open = input.peek().span;
2568
2569    // Check for enhanced for: Type ident : expr
2570    // Or regular for: init; cond; update
2571    let saved = input.cursor();
2572
2573    // Try enhanced for
2574    if let Some(stmt) = try_parse_enhanced_for(for_span, open, input, leading_comments.clone()) {
2575        return Ok(stmt);
2576    }
2577    input.set_cursor(saved);
2578
2579    // Regular for
2580    let init = if input.is(&TokenKind::Semicolon) {
2581        input.next();
2582        ForInit::Exprs(Vec::new())
2583    } else {
2584        // Could be local var decl or expression list
2585        let inner_saved = input.cursor();
2586        if let Some(var_decl) = try_parse_local_var_decl(input) {
2587            ForInit::LocalVarDecl(var_decl)
2588        } else {
2589            input.set_cursor(inner_saved);
2590            let mut exprs = Vec::new();
2591            exprs.push(parse_expression(input)?);
2592            while input.eat(&TokenKind::Comma) {
2593                exprs.push(parse_expression(input)?);
2594            }
2595            input.expect(TokenKind::Semicolon)?;
2596            ForInit::Exprs(exprs)
2597        }
2598    };
2599
2600    let cond = if input.is(&TokenKind::Semicolon) {
2601        input.next();
2602        None
2603    } else {
2604        let semi1 = Some(input.peek().span);
2605        let cond = parse_expression(input)?;
2606        input.expect(TokenKind::Semicolon)?;
2607        let _ = semi1;
2608        Some(cond)
2609    };
2610
2611    let mut update = Vec::new();
2612    while !input.is(&TokenKind::RParen) && !input.is_empty() {
2613        update.push(parse_expression(input)?);
2614        input.eat(&TokenKind::Comma);
2615    }
2616    input.expect(TokenKind::RParen)?;
2617    let close = input.peek().span;
2618    let body = parse_statement(input)?;
2619
2620    Ok(Stmt::For(ForStmt {
2621        leading_comments,
2622        for_span,
2623        paren_span: (open, close),
2624        init,
2625        cond,
2626        semi2_span: None,
2627        update,
2628        body: Box::new(body),
2629    }))
2630}
2631
2632fn try_parse_local_var_decl(input: &ParseStream) -> Option<LocalVarDeclStmt> {
2633    let modifiers = parse_modifiers(input);
2634    let is_var = input.is(&TokenKind::Var);
2635    let can_start = crate::token::can_start_type(&input.peek().kind);
2636
2637    if is_var || can_start {
2638        let saved = input.cursor();
2639        let ty_result = if is_var {
2640            let var_span = input.peek().span;
2641            input.next();
2642            Ok(LocalVarType::Var(var_span))
2643        } else {
2644            parse_type(input).map(LocalVarType::Type)
2645        };
2646
2647        if let Ok(ty) = ty_result
2648            && input.is_any_ident()
2649        {
2650            let name = input.parse_ident().ok()?;
2651            let dims = parse_array_dims(input).ok().unwrap_or_default();
2652            let initializer = if input.eat(&TokenKind::Eq) {
2653                parse_expression(input).ok()
2654            } else {
2655                None
2656            };
2657            let mut declarators = vec![VariableDeclarator {
2658                name: Some(name),
2659                dims,
2660                initializer,
2661            }];
2662            while input.eat(&TokenKind::Comma) {
2663                let name = input.parse_ident().ok()?;
2664                let dims = parse_array_dims(input).ok().unwrap_or_default();
2665                let init = if input.eat(&TokenKind::Eq) {
2666                    parse_expression(input).ok()
2667                } else {
2668                    None
2669                };
2670                declarators.push(VariableDeclarator {
2671                    name: Some(name),
2672                    dims,
2673                    initializer: init,
2674                });
2675            }
2676            if input.eat(&TokenKind::Semicolon) {
2677                let semi_span = input.peek().span;
2678                return Some(LocalVarDeclStmt {
2679                    leading_comments: Vec::new(),
2680                    modifiers,
2681                    ty,
2682                    declarators,
2683                    semi_span,
2684                });
2685            }
2686        }
2687        input.set_cursor(saved);
2688    }
2689    None
2690}
2691
2692fn try_parse_enhanced_for(
2693    for_span: Span,
2694    open: Span,
2695    input: &ParseStream,
2696    leading_comments: Vec<Comment>,
2697) -> Option<Stmt> {
2698    let modifiers = parse_modifiers(input);
2699    let is_var = input.is(&TokenKind::Var);
2700    let can_start = crate::token::can_start_type(&input.peek().kind);
2701
2702    if !is_var && !can_start {
2703        input.set_cursor(input.cursor()); // already advanced by parse_modifiers
2704        return None;
2705    }
2706
2707    let saved = input.cursor();
2708    let ty_result = if is_var {
2709        let var_span = input.peek().span;
2710        input.next();
2711        Ok(LocalVarType::Var(var_span))
2712    } else {
2713        parse_type(input).map(LocalVarType::Type)
2714    };
2715
2716    if let Ok(ty) = ty_result
2717        && input.is_any_ident()
2718    {
2719        let name = input.parse_ident().ok()?;
2720        let dims = parse_array_dims(input).ok().unwrap_or_default();
2721        if input.eat(&TokenKind::Colon) {
2722            let colon_span = input.peek().span;
2723            let iterable = parse_expression(input).ok()?;
2724            input.expect(TokenKind::RParen).ok()?;
2725            let close = input.peek().span;
2726            let body = parse_statement(input).ok()?;
2727            return Some(Stmt::EnhancedFor(EnhancedForStmt {
2728                leading_comments,
2729                for_span,
2730                paren_span: (open, close),
2731                var_decl: LocalVarDeclStmt {
2732                    leading_comments: Vec::new(),
2733                    modifiers,
2734                    ty,
2735                    declarators: vec![VariableDeclarator {
2736                        name: Some(name),
2737                        dims,
2738                        initializer: None,
2739                    }],
2740                    semi_span: Span::call_site(),
2741                },
2742                colon_span,
2743                iterable,
2744                body: Box::new(body),
2745            }));
2746        }
2747    }
2748    input.set_cursor(saved);
2749    None
2750}
2751
2752fn parse_jump_stmt(
2753    input: &ParseStream,
2754    keyword: TokenKind,
2755    make_stmt: fn(JumpStmt) -> Stmt,
2756    leading_comments: Vec<Comment>,
2757) -> Result<Stmt> {
2758    let keyword_span = input.peek().span;
2759    input.expect(keyword)?;
2760    let label = if input.is_any_ident() && !input.is(&TokenKind::Semicolon) {
2761        let saved = input.cursor();
2762        let ident = input.parse_ident().ok();
2763        if ident.is_some() && (input.is(&TokenKind::Semicolon) || input.is_empty()) {
2764            ident
2765        } else {
2766            input.set_cursor(saved);
2767            None
2768        }
2769    } else {
2770        None
2771    };
2772    input.expect(TokenKind::Semicolon)?;
2773    let semi_span = input.peek().span;
2774    Ok(make_stmt(JumpStmt {
2775        leading_comments,
2776        keyword_span,
2777        label,
2778        semi_span,
2779    }))
2780}
2781
2782fn parse_return_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2783    let return_span = input.peek().span;
2784    input.expect(TokenKind::Return)?;
2785    let value = if input.is(&TokenKind::Semicolon) {
2786        None
2787    } else {
2788        Some(parse_expression(input)?)
2789    };
2790    input.expect(TokenKind::Semicolon)?;
2791    let semi_span = input.peek().span;
2792    Ok(Stmt::Return(ReturnStmt {
2793        leading_comments,
2794        return_span,
2795        value,
2796        semi_span,
2797    }))
2798}
2799
2800fn parse_throw_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2801    let throw_span = input.peek().span;
2802    input.expect(TokenKind::Throw)?;
2803    let expr = parse_expression(input)?;
2804    input.expect(TokenKind::Semicolon)?;
2805    let semi_span = input.peek().span;
2806    Ok(Stmt::Throw(ThrowStmt {
2807        leading_comments,
2808        throw_span,
2809        expr,
2810        semi_span,
2811    }))
2812}
2813
2814fn parse_synchronized_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2815    let synchronized_span = input.peek().span;
2816    input.expect(TokenKind::Synchronized)?;
2817    input.expect(TokenKind::LParen)?;
2818    let open = input.peek().span;
2819    let lock = parse_expression(input)?;
2820    input.expect(TokenKind::RParen)?;
2821    let close = input.peek().span;
2822    let body = parse_block(input, Vec::new())?;
2823    Ok(Stmt::Synchronized(SynchronizedStmt {
2824        leading_comments,
2825        synchronized_span,
2826        paren_span: (open, close),
2827        lock,
2828        body,
2829    }))
2830}
2831
2832fn parse_try_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2833    let try_span = input.peek().span;
2834    input.expect(TokenKind::Try)?;
2835
2836    if input.is(&TokenKind::LParen) {
2837        // Try-with-resources
2838        input.expect(TokenKind::LParen)?;
2839        let open = input.peek().span;
2840        let mut resources = Vec::new();
2841        loop {
2842            let saved = input.cursor();
2843            // Try parsing as a local var decl (without requiring semicolon)
2844            let modifiers = parse_modifiers(input);
2845            let is_var = input.is(&TokenKind::Var);
2846            let can_start = crate::token::can_start_type(&input.peek().kind);
2847            if is_var || can_start {
2848                let ty_result = if is_var {
2849                    let var_span = input.peek().span;
2850                    input.next();
2851                    Ok(LocalVarType::Var(var_span))
2852                } else {
2853                    parse_type(input).map(LocalVarType::Type)
2854                };
2855                if let Ok(ty) = ty_result
2856                    && input.is_any_ident()
2857                    && let Ok(name) = input.parse_ident()
2858                {
2859                    let dims = parse_array_dims(input).unwrap_or_default();
2860                    let initializer = if input.eat(&TokenKind::Eq) {
2861                        parse_expression(input).ok()
2862                    } else {
2863                        None
2864                    };
2865                    let declarators = vec![VariableDeclarator {
2866                        name: Some(name),
2867                        dims,
2868                        initializer,
2869                    }];
2870                    resources.push(TryResource::Decl(LocalVarDeclStmt {
2871                        leading_comments: Vec::new(),
2872                        modifiers,
2873                        ty,
2874                        declarators,
2875                        semi_span: Span::call_site(),
2876                    }));
2877                    if !input.eat(&TokenKind::Semicolon) {
2878                        break;
2879                    }
2880                    if input.is(&TokenKind::RParen) {
2881                        break;
2882                    }
2883                    continue;
2884                }
2885            }
2886            input.set_cursor(saved);
2887            let ident = input.parse_ident()?;
2888            resources.push(TryResource::VarRef(ident));
2889            if !input.eat(&TokenKind::Semicolon) {
2890                break;
2891            }
2892            if input.is(&TokenKind::RParen) {
2893                break;
2894            }
2895        }
2896        input.expect(TokenKind::RParen)?;
2897        let close = input.peek().span;
2898        let block = parse_block(input, Vec::new())?;
2899        let catches = parse_catch_clauses(input)?;
2900        let finally_block = parse_finally_clause(input);
2901        Ok(Stmt::Try(TryStmt::TryWithResources {
2902            leading_comments,
2903            try_span,
2904            paren_span: (open, close),
2905            resources,
2906            block,
2907            catches,
2908            finally_block,
2909        }))
2910    } else {
2911        let block = parse_block(input, Vec::new())?;
2912        let catches = parse_catch_clauses(input)?;
2913        let finally_block = parse_finally_clause(input);
2914        Ok(Stmt::Try(TryStmt::Basic {
2915            leading_comments,
2916            try_span,
2917            block,
2918            catches,
2919            finally_block,
2920        }))
2921    }
2922}
2923
2924fn parse_catch_clauses(input: &ParseStream) -> Result<Vec<CatchClause>> {
2925    let mut clauses = Vec::new();
2926    while input.is(&TokenKind::Catch) {
2927        let catch_span = input.peek().span;
2928        input.next();
2929        input.expect(TokenKind::LParen).ok();
2930        let open = input.peek().span;
2931        let modifiers = parse_modifiers(input);
2932        let mut types = Vec::new();
2933        types.push(parse_type(input)?);
2934        while input.eat(&TokenKind::Pipe) {
2935            types.push(parse_type(input)?);
2936        }
2937        let name = input.parse_ident()?;
2938        input.expect(TokenKind::RParen).ok();
2939        let close = input.peek().span;
2940        let block = parse_block(input, Vec::new())?;
2941        clauses.push(CatchClause {
2942            catch_span,
2943            paren_span: (open, close),
2944            param: CatchParam {
2945                modifiers,
2946                ty: CatchType { types },
2947                name,
2948            },
2949            block,
2950        });
2951    }
2952    Ok(clauses)
2953}
2954
2955fn parse_finally_clause(input: &ParseStream) -> Option<(Span, Block)> {
2956    if input.eat(&TokenKind::Finally) {
2957        let finally_span = input.peek().span;
2958        let block = parse_block(input, Vec::new()).ok()?;
2959        Some((finally_span, block))
2960    } else {
2961        None
2962    }
2963}
2964
2965fn parse_yield_stmt(input: &ParseStream, leading_comments: Vec<Comment>) -> Result<Stmt> {
2966    let yield_span = input.peek().span;
2967    input.expect(TokenKind::Yield)?;
2968    let value = parse_expression(input)?;
2969    input.expect(TokenKind::Semicolon)?;
2970    let semi_span = input.peek().span;
2971    Ok(Stmt::Yield(YieldStmt {
2972        leading_comments,
2973        yield_span,
2974        value,
2975        semi_span,
2976    }))
2977}
2978
2979// ============================================================================
2980// Expressions (Pratt parser)
2981// ============================================================================
2982
2983fn parse_expression(input: &ParseStream) -> Result<Expr> {
2984    parse_assignment_expr(input)
2985}
2986
2987fn parse_assignment_expr(input: &ParseStream) -> Result<Expr> {
2988    let left = parse_conditional_expr(input)?;
2989
2990    if is_assignment_op(&input.peek().kind) {
2991        let op = parse_assign_op(input)?;
2992        let value = parse_assignment_expr(input)?;
2993        let target = expr_to_assign_target(left)?;
2994        return Ok(Expr::Assign(AssignExpr {
2995            target,
2996            op,
2997            value: Box::new(value),
2998        }));
2999    }
3000
3001    Ok(left)
3002}
3003
3004fn is_assignment_op(kind: &TokenKind) -> bool {
3005    matches!(
3006        kind,
3007        TokenKind::Eq
3008            | TokenKind::PlusEq
3009            | TokenKind::MinusEq
3010            | TokenKind::StarEq
3011            | TokenKind::SlashEq
3012            | TokenKind::AmpEq
3013            | TokenKind::PipeEq
3014            | TokenKind::CaretEq
3015            | TokenKind::PercentEq
3016            | TokenKind::LtLtEq
3017            | TokenKind::GtGtEq
3018            | TokenKind::GtGtGtEq
3019    )
3020}
3021
3022fn parse_assign_op(input: &ParseStream) -> Result<AssignOpToken> {
3023    let span = input.peek().span;
3024    let op = match &input.peek().kind {
3025        TokenKind::Eq => AssignOp::Assign,
3026        TokenKind::PlusEq => AssignOp::AddAssign,
3027        TokenKind::MinusEq => AssignOp::SubAssign,
3028        TokenKind::StarEq => AssignOp::MulAssign,
3029        TokenKind::SlashEq => AssignOp::DivAssign,
3030        TokenKind::AmpEq => AssignOp::AndAssign,
3031        TokenKind::PipeEq => AssignOp::OrAssign,
3032        TokenKind::CaretEq => AssignOp::XorAssign,
3033        TokenKind::PercentEq => AssignOp::RemAssign,
3034        TokenKind::LtLtEq => AssignOp::LShiftAssign,
3035        TokenKind::GtGtEq => AssignOp::RShiftAssign,
3036        TokenKind::GtGtGtEq => AssignOp::URShiftAssign,
3037        _ => {
3038            return Err(crate::error::Error::new(
3039                span,
3040                "expected assignment operator",
3041            ));
3042        }
3043    };
3044    input.next();
3045    Ok(AssignOpToken { op, span })
3046}
3047
3048fn expr_to_assign_target(expr: Expr) -> Result<AssignTarget> {
3049    match expr {
3050        Expr::Ident(i) => Ok(AssignTarget::Ident(i)),
3051        Expr::FieldAccess(f) => Ok(AssignTarget::FieldAccess(f)),
3052        Expr::ArrayAccess(a) => Ok(AssignTarget::ArrayAccess(a)),
3053        _ => Err(crate::error::Error::new(
3054            expr.span(),
3055            "invalid assignment target",
3056        )),
3057    }
3058}
3059
3060fn parse_conditional_expr(input: &ParseStream) -> Result<Expr> {
3061    let expr = parse_binary_expr(input, 0)?;
3062    if input.eat(&TokenKind::Question) {
3063        let question_span = input.peek().span;
3064        let then_expr = parse_expression(input)?;
3065        input.expect(TokenKind::Colon)?;
3066        let colon_span = input.peek().span;
3067        let else_expr = parse_conditional_expr(input)?;
3068        return Ok(Expr::Conditional(ConditionalExpr {
3069            cond: Box::new(expr),
3070            question_span,
3071            then_expr: Box::new(then_expr),
3072            colon_span,
3073            else_expr: Box::new(else_expr),
3074        }));
3075    }
3076    Ok(expr)
3077}
3078
3079fn get_precedence(kind: &TokenKind) -> u8 {
3080    match kind {
3081        TokenKind::PipePipe => 1,
3082        TokenKind::AmpAmp => 2,
3083        TokenKind::Pipe => 3,
3084        TokenKind::Caret => 4,
3085        TokenKind::Amp => 5,
3086        TokenKind::EqEq | TokenKind::BangEq => 6,
3087        TokenKind::Lt
3088        | TokenKind::Gt
3089        | TokenKind::LtEq
3090        | TokenKind::GtEq
3091        | TokenKind::Instanceof => 7,
3092        TokenKind::LtLt | TokenKind::GtGt | TokenKind::GtGtGt => 8,
3093        TokenKind::Plus | TokenKind::Minus => 9,
3094        TokenKind::Star | TokenKind::Slash | TokenKind::Percent => 10,
3095        _ => 0,
3096    }
3097}
3098
3099fn token_to_bin_op(kind: &TokenKind) -> Option<crate::ast::op::BinOp> {
3100    use crate::ast::op::BinOp::*;
3101    Some(match kind {
3102        TokenKind::Plus => Add,
3103        TokenKind::Minus => Sub,
3104        TokenKind::Star => Mul,
3105        TokenKind::Slash => Div,
3106        TokenKind::Percent => Rem,
3107        TokenKind::Amp => And,
3108        TokenKind::Pipe => Or,
3109        TokenKind::Caret => Xor,
3110        TokenKind::LtLt => LShift,
3111        TokenKind::GtGt => RShift,
3112        TokenKind::GtGtGt => URShift,
3113        TokenKind::EqEq => Eq,
3114        TokenKind::BangEq => Ne,
3115        TokenKind::Lt => Lt,
3116        TokenKind::Gt => Gt,
3117        TokenKind::LtEq => Le,
3118        TokenKind::GtEq => Ge,
3119        TokenKind::AmpAmp => LAnd,
3120        TokenKind::PipePipe => LOr,
3121        _ => return None,
3122    })
3123}
3124
3125fn parse_binary_expr(input: &ParseStream, min_prec: u8) -> Result<Expr> {
3126    let mut left = parse_unary_expr(input)?;
3127
3128    loop {
3129        let prec = get_precedence(&input.peek().kind);
3130        if prec == 0 || prec < min_prec {
3131            break;
3132        }
3133
3134        if input.is(&TokenKind::Instanceof) {
3135            let instanceof_span = input.peek().span;
3136            input.next();
3137
3138            // Handle 'final' modifier in patterns (Java 16+)
3139            let _has_final = input.eat(&TokenKind::Final);
3140
3141            let ty = parse_type(input)?;
3142            let ty_span = ty.span();
3143
3144            if input.is(&TokenKind::LParen) {
3145                // Record pattern: instanceof Point(int x, int y)
3146                input.next(); // consume '('
3147                let mut components = Vec::new();
3148                while !input.is(&TokenKind::RParen) && !input.is_empty() {
3149                    components.push(parse_pattern(input)?);
3150                    input.eat(&TokenKind::Comma);
3151                }
3152                input.expect(TokenKind::RParen)?;
3153                let end = input.peek().span;
3154                left = Expr::Instanceof(InstanceofExpr {
3155                    expr: Box::new(left),
3156                    instanceof_span,
3157                    pattern: InstanceofPattern::Pattern(Pattern::RecordPattern(RecordPattern {
3158                        record_type: ty,
3159                        components,
3160                        span: ty_span.join(end),
3161                    })),
3162                });
3163                continue;
3164            } else if input.is_any_ident() {
3165                // Type pattern: instanceof String s
3166                let name = input.parse_ident()?;
3167                left = Expr::Instanceof(InstanceofExpr {
3168                    expr: Box::new(left),
3169                    instanceof_span,
3170                    pattern: InstanceofPattern::Pattern(Pattern::TypePattern(TypePattern {
3171                        annotations: vec![],
3172                        ty,
3173                        name: Some(name),
3174                        span: ty_span.join(input.peek().span),
3175                    })),
3176                });
3177                continue;
3178            } else {
3179                left = Expr::Instanceof(InstanceofExpr {
3180                    expr: Box::new(left),
3181                    instanceof_span,
3182                    pattern: InstanceofPattern::Type(ty),
3183                });
3184                continue;
3185            }
3186        }
3187
3188        let op = match token_to_bin_op(&input.peek().kind) {
3189            Some(op) => op,
3190            None => break,
3191        };
3192        let op_span = input.peek().span;
3193        input.next();
3194
3195        let right = parse_binary_expr(input, prec + 1)?;
3196        left = Expr::Binary(BinaryExpr {
3197            left: Box::new(left),
3198            op: BinOpToken { op, span: op_span },
3199            right: Box::new(right),
3200        });
3201    }
3202
3203    Ok(left)
3204}
3205
3206fn can_start_unary_expr(kind: &TokenKind) -> bool {
3207    matches!(
3208        kind,
3209        TokenKind::Plus
3210            | TokenKind::Minus
3211            | TokenKind::Bang
3212            | TokenKind::Tilde
3213            | TokenKind::PlusPlus
3214            | TokenKind::MinusMinus
3215            | TokenKind::LParen
3216            | TokenKind::New
3217            | TokenKind::Super
3218            | TokenKind::This
3219            | TokenKind::IntegerLit(_)
3220            | TokenKind::FloatLit(_)
3221            | TokenKind::StringLit(_)
3222            | TokenKind::CharLit(_)
3223            | TokenKind::BoolLit(_)
3224            | TokenKind::NullLit
3225            | TokenKind::Ident(_)
3226            | TokenKind::Record
3227            | TokenKind::Sealed
3228            | TokenKind::Var
3229            | TokenKind::Yield
3230            | TokenKind::Open
3231            | TokenKind::Provides
3232            | TokenKind::Requires
3233            | TokenKind::Uses
3234            | TokenKind::With
3235            | TokenKind::When
3236            | TokenKind::To
3237            | TokenKind::Exports
3238            | TokenKind::Opens
3239            | TokenKind::Transitive
3240            | TokenKind::Byte
3241            | TokenKind::Short
3242            | TokenKind::Int
3243            | TokenKind::Long
3244            | TokenKind::Char
3245            | TokenKind::Float
3246            | TokenKind::Double
3247            | TokenKind::Boolean
3248            | TokenKind::Switch
3249    )
3250}
3251
3252fn token_to_unary_op(kind: &TokenKind) -> Option<UnaryOp> {
3253    match kind {
3254        TokenKind::Minus => Some(UnaryOp::Neg),
3255        TokenKind::Bang => Some(UnaryOp::Not),
3256        TokenKind::Tilde => Some(UnaryOp::BitNot),
3257        TokenKind::PlusPlus => Some(UnaryOp::PreInc),
3258        TokenKind::MinusMinus => Some(UnaryOp::PreDec),
3259        _ => None,
3260    }
3261}
3262
3263fn parse_unary_expr(input: &ParseStream) -> Result<Expr> {
3264    let span = input.peek().span;
3265    if input.is(&TokenKind::Plus) {
3266        input.next();
3267        return parse_unary_expr(input);
3268    }
3269    if let Some(op) = token_to_unary_op(&input.peek().kind) {
3270        input.next();
3271        let expr = parse_unary_expr(input)?;
3272        return Ok(Expr::Unary(UnaryExpr {
3273            op,
3274            op_span: span,
3275            expr: Box::new(expr),
3276            is_postfix: false,
3277        }));
3278    }
3279    parse_postfix_expr(input)
3280}
3281
3282fn parse_postfix_expr(input: &ParseStream) -> Result<Expr> {
3283    let mut expr = parse_primary_expr(input)?;
3284
3285    loop {
3286        match &input.peek().kind {
3287            TokenKind::Dot => {
3288                let dot_span = input.peek().span;
3289                input.next();
3290                if input.is(&TokenKind::New) {
3291                    // Inner class creation: Outer.new InnerType(...)
3292                    let new_span = input.peek().span;
3293                    input.next();
3294                    let type_args = parse_optional_type_arguments(input);
3295                    let class_type = parse_path(input)?;
3296                    input.expect(TokenKind::LParen)?;
3297                    let open = input.peek().span;
3298                    let args = input.parse_terminated(parse_expression)?;
3299                    input.expect(TokenKind::RParen)?;
3300                    let close = input.peek().span;
3301                    let body = if input.is(&TokenKind::LBrace) {
3302                        let dl = parse_class_body_decl_list(input)?;
3303                        Some(dl)
3304                    } else {
3305                        None
3306                    };
3307                    expr = Expr::NewClass(NewClassExpr {
3308                        new_span,
3309                        type_args,
3310                        class_type,
3311                        paren_span: (open, close),
3312                        args,
3313                        body,
3314                    });
3315                } else if input.is(&TokenKind::This) {
3316                    let this_span = input.peek().span;
3317                    input.next();
3318                    expr = Expr::FieldAccess(FieldAccessExpr {
3319                        target: Box::new(expr),
3320                        dot_span,
3321                        field: Ident::new("this".to_string(), this_span),
3322                    });
3323                } else if input.is(&TokenKind::Class) {
3324                    let class_span = input.peek().span;
3325                    input.next();
3326                    let ty = expr_to_type(&expr)?;
3327                    expr = Expr::ClassLit {
3328                        type_expr: Box::new(ty),
3329                        dot_span,
3330                        class_span,
3331                    };
3332                } else if input.is(&TokenKind::Super) {
3333                    let super_span = input.peek().span;
3334                    input.next();
3335                    if input.is(&TokenKind::ColonColon) {
3336                        let colon_colon_span = input.peek().span;
3337                        input.next();
3338                        let type_args = parse_optional_type_arguments(input);
3339                        let method_name = input.parse_ident()?;
3340                        expr = Expr::MethodRef(MethodRefExpr {
3341                            target: MethodRefTarget::SuperFromType {
3342                                type_name: expr_to_path(expr)?,
3343                                dot_span,
3344                                super_span,
3345                            },
3346                            colon_colon_span,
3347                            type_args,
3348                            method_name,
3349                        });
3350                    } else if input.is(&TokenKind::Dot) {
3351                        // Qualified super method call: Outer.super.method(args)
3352                        // Treat Outer.super as a special expression and continue parsing
3353                        // the .method() part in the next iteration
3354                        expr = Expr::FieldAccess(FieldAccessExpr {
3355                            target: Box::new(expr),
3356                            dot_span,
3357                            field: Ident::new("super".to_string(), super_span),
3358                        });
3359                    } else {
3360                        return Err(crate::error::Error::new(super_span, "unexpected super"));
3361                    }
3362                } else if input.is(&TokenKind::New) {
3363                    let _ = input.next();
3364                    // Inner class creation
3365                    continue;
3366                } else if input.is(&TokenKind::Lt) {
3367                    // Explicit type arguments: obj.<Type>method(args)
3368                    let type_args = parse_type_arguments(input)?;
3369                    let method = input.parse_ident()?;
3370                    input.expect(TokenKind::LParen)?;
3371                    let open = input.peek().span;
3372                    let args = input.parse_terminated(parse_expression)?;
3373                    input.expect(TokenKind::RParen)?;
3374                    let close = input.peek().span;
3375                    expr = Expr::MethodCall(MethodCallExpr {
3376                        receiver: Some(Box::new(expr)),
3377                        type_args: Some(type_args),
3378                        method,
3379                        paren_span: (open, close),
3380                        args,
3381                    });
3382                } else {
3383                    let field = input.parse_ident().unwrap_or_else(|_| {
3384                        let sp = input.peek().span;
3385                        let name = format!("{}", input.peek().kind);
3386                        input.next();
3387                        Ident::new(name, sp)
3388                    });
3389                    expr = Expr::FieldAccess(FieldAccessExpr {
3390                        target: Box::new(expr),
3391                        dot_span,
3392                        field,
3393                    });
3394                }
3395            }
3396            TokenKind::LParen => {
3397                // Method call or cast
3398                // If current expr is a simple ident, it's a method call
3399                let open = input.peek().span;
3400                input.next();
3401                let args = input.parse_terminated(parse_expression)?;
3402                input.expect(TokenKind::RParen)?;
3403                let close = input.peek().span;
3404
3405                // Check if this was actually a cast: (Type) expr
3406                // Cast is handled in primary, so this is always a method call
3407                let (method, receiver) = match &expr {
3408                    Expr::Ident(name) => (name.clone(), None),
3409                    Expr::FieldAccess(f) => {
3410                        (f.field.clone(), Some(Box::new(f.target.as_ref().clone())))
3411                    }
3412                    _ => return Err(crate::error::Error::new(open, "expected method name")),
3413                };
3414
3415                // Check for type arguments before the method call
3416                // Actually type args are before the name, e.g., name.<Type>method()
3417                // This should be handled differently...
3418
3419                expr = Expr::MethodCall(MethodCallExpr {
3420                    receiver,
3421                    type_args: None,
3422                    method,
3423                    paren_span: (open, close),
3424                    args,
3425                });
3426            }
3427            TokenKind::LBracket => {
3428                let open = input.peek().span;
3429                input.next();
3430                // Check for empty brackets `[]` — could be array type suffix
3431                // before `.class` or `::` (e.g., `float[].class`, `String[]::new`)
3432                if input.is(&TokenKind::RBracket) {
3433                    input.next();
3434                    let close = input.peek().span;
3435                    // Collect more `[]` pairs
3436                    let mut dims = vec![crate::ast::ArrayDim {
3437                        bracket_span: (open, close),
3438                        annotations: vec![],
3439                    }];
3440                    while input.is(&TokenKind::LBracket) {
3441                        let d_open = input.peek().span;
3442                        input.next();
3443                        input.expect(TokenKind::RBracket)?;
3444                        let d_close = input.peek().span;
3445                        dims.push(crate::ast::ArrayDim {
3446                            bracket_span: (d_open, d_close),
3447                            annotations: vec![],
3448                        });
3449                    }
3450                    // Now check if `.class` or `::` follows — if so, this is a type suffix
3451                    if input.is(&TokenKind::Dot) && input.look_ahead(1).kind == TokenKind::Class {
3452                        // Type suffix: convert expr to type, then handle .class
3453                        let base_ty = expr_to_type(&expr)?;
3454                        let span = base_ty.span().join(dims.last().unwrap().bracket_span.1);
3455                        let ty = Type::Reference(ReferenceType::Array(ArrayType {
3456                            elem_type: Box::new(base_ty),
3457                            dims,
3458                            span,
3459                        }));
3460                        let dot_span = input.peek().span;
3461                        input.next(); // consume '.'
3462                        let class_span = input.peek().span;
3463                        input.next(); // consume 'class'
3464                        expr = Expr::ClassLit {
3465                            type_expr: Box::new(ty),
3466                            dot_span,
3467                            class_span,
3468                        };
3469                    } else if input.is(&TokenKind::ColonColon) {
3470                        // Method reference with array type: e.g., `ComponentName[]::new`
3471                        // Skip the `[]` — the `::` handler below will handle the rest
3472                        // The expression remains as the base identifier, which will be
3473                        // converted to a path by the `::` handler. Not perfect for array
3474                        // types but better than failing.
3475                        // Leave expr as-is (the base identifier)
3476                    } else {
3477                        // Standalone empty `[]` — probably a syntax error in context,
3478                        // but recover gracefully by treating as array type expression
3479                        expr =
3480                            Expr::Ident(crate::ident::Ident::new("_array_type_".to_string(), open));
3481                    }
3482                } else {
3483                    let index = parse_expression(input)?;
3484                    input.expect(TokenKind::RBracket)?;
3485                    let close = input.peek().span;
3486                    expr = Expr::ArrayAccess(ArrayAccessExpr {
3487                        array: Box::new(expr),
3488                        index: Box::new(index),
3489                        bracket_span: (open, close),
3490                    });
3491                }
3492            }
3493            TokenKind::PlusPlus => {
3494                let op_span = input.peek().span;
3495                input.next();
3496                expr = Expr::Unary(UnaryExpr {
3497                    op: UnaryOp::PostInc,
3498                    op_span,
3499                    expr: Box::new(expr),
3500                    is_postfix: true,
3501                });
3502            }
3503            TokenKind::MinusMinus => {
3504                let op_span = input.peek().span;
3505                input.next();
3506                expr = Expr::Unary(UnaryExpr {
3507                    op: UnaryOp::PostDec,
3508                    op_span,
3509                    expr: Box::new(expr),
3510                    is_postfix: true,
3511                });
3512            }
3513            TokenKind::ColonColon => {
3514                let colon_colon_span = input.peek().span;
3515                input.next();
3516                let type_args = parse_optional_type_arguments(input);
3517                if input.is(&TokenKind::New) {
3518                    // Constructor reference
3519                    let method_name = Ident::new("new".to_string(), input.peek().span);
3520                    input.next();
3521                    expr = Expr::MethodRef(MethodRefExpr {
3522                        target: MethodRefTarget::Type(expr_to_path(expr)?),
3523                        colon_colon_span,
3524                        type_args,
3525                        method_name,
3526                    });
3527                } else {
3528                    let method_name = input.parse_ident()?;
3529                    match &expr {
3530                        Expr::Ident(_) => {
3531                            expr = Expr::MethodRef(MethodRefExpr {
3532                                target: MethodRefTarget::Type(expr_to_path(expr)?),
3533                                colon_colon_span,
3534                                type_args,
3535                                method_name,
3536                            });
3537                        }
3538                        _ => {
3539                            expr = Expr::MethodRef(MethodRefExpr {
3540                                target: MethodRefTarget::Expr(Box::new(expr)),
3541                                colon_colon_span,
3542                                type_args,
3543                                method_name,
3544                            });
3545                        }
3546                    }
3547                }
3548            }
3549            _ => break,
3550        }
3551    }
3552
3553    Ok(expr)
3554}
3555
3556fn expr_to_type(expr: &Expr) -> Result<Type> {
3557    match expr {
3558        Expr::Ident(i) => match i.name.as_str() {
3559            "byte" => Ok(Type::Primitive(PrimitiveType::Byte)),
3560            "short" => Ok(Type::Primitive(PrimitiveType::Short)),
3561            "int" => Ok(Type::Primitive(PrimitiveType::Int)),
3562            "long" => Ok(Type::Primitive(PrimitiveType::Long)),
3563            "char" => Ok(Type::Primitive(PrimitiveType::Char)),
3564            "float" => Ok(Type::Primitive(PrimitiveType::Float)),
3565            "double" => Ok(Type::Primitive(PrimitiveType::Double)),
3566            "boolean" => Ok(Type::Primitive(PrimitiveType::Boolean)),
3567            "void" => Ok(Type::Void(i.span())),
3568            _ => Ok(Type::Reference(ReferenceType::ClassOrInterfaceType(
3569                ClassOrInterfaceType {
3570                    path: Path::from_ident(i.clone()),
3571                    annotations_prefix: vec![],
3572                },
3573            ))),
3574        },
3575        Expr::FieldAccess(_) => {
3576            let path = expr_to_path(expr.clone())?;
3577            Ok(Type::Reference(ReferenceType::ClassOrInterfaceType(
3578                ClassOrInterfaceType {
3579                    path,
3580                    annotations_prefix: vec![],
3581                },
3582            )))
3583        }
3584        _ => Err(crate::error::Error::new(expr.span(), "expected type")),
3585    }
3586}
3587
3588fn expr_to_path(expr: Expr) -> Result<Path> {
3589    match expr {
3590        Expr::Ident(i) => Ok(Path::from_ident(i)),
3591        Expr::FieldAccess(f) => {
3592            let mut target_path = expr_to_path(*f.target)?;
3593            target_path.segments.push(PathSegment {
3594                ident: f.field,
3595                args: None,
3596            });
3597            Ok(target_path)
3598        }
3599        _ => Err(crate::error::Error::new(expr.span(), "expected type name")),
3600    }
3601}
3602
3603fn parse_primary_expr(input: &ParseStream) -> Result<Expr> {
3604    let span = input.peek().span;
3605
3606    // Parenthesized expression, cast, or lambda
3607    if input.is(&TokenKind::LParen) {
3608        let open = span;
3609        input.next();
3610
3611        // Try to determine if this is a cast, lambda, or parenthesized expression
3612        let saved = input.cursor();
3613
3614        // Try parsing as type + ')' for cast
3615        if let Ok(ty) = parse_type(input) {
3616            // Handle intersection types: (Type & Type & ...) expr
3617            let mut intersection_types = Vec::new();
3618            while input.eat(&TokenKind::Amp) {
3619                if let Ok(ty) = parse_type(input) {
3620                    intersection_types.push(ty);
3621                } else {
3622                    break;
3623                }
3624            }
3625
3626            if input.is(&TokenKind::RParen) {
3627                // Check if what follows ')' can start a cast operand (unary expression).
3628                // If not (e.g., '?', ')', ';'), this is likely a parenthesized expression, not a cast.
3629                let next_after_rparen = input.look_ahead(1);
3630                let can_be_cast = can_start_unary_expr(&next_after_rparen.kind);
3631
3632                if can_be_cast {
3633                    input.next();
3634                    let close = input.peek().span;
3635                    // Could be cast or lambda with typed params
3636                    // If next is '->', it's a lambda
3637                    if input.is(&TokenKind::Arrow) {
3638                        let arrow_span = input.peek().span;
3639                        input.next();
3640                        let body = parse_lambda_body(input)?;
3641                        return Ok(Expr::Lambda(LambdaExpr {
3642                            params: LambdaParams::List {
3643                                paren_span: (open, close),
3644                                params: vec![LambdaParam {
3645                                    modifiers: vec![],
3646                                    ty,
3647                                    name: crate::ident::Ident::new("_".to_string(), span),
3648                                }],
3649                            },
3650                            arrow_span,
3651                            body,
3652                            span: open.join(input.peek().span),
3653                        }));
3654                    }
3655                    let expr = parse_unary_expr(input)?;
3656                    // For intersection types, we create a special cast expression
3657                    // For now, we just use the first type (could be enhanced later)
3658                    return Ok(Expr::Cast(CastExpr {
3659                        paren_span: (open, close),
3660                        target_type: ty,
3661                        expr: Box::new(expr),
3662                    }));
3663                }
3664            }
3665        }
3666
3667        input.set_cursor(saved);
3668
3669        // Check for lambda: () -> ... or (params) -> ...
3670        // Cursor is at ')' (the first token after the consumed '(').
3671        // Scan forward: look_ahead(0) is ')', which matches our '('.
3672        {
3673            let lambda_saved = input.cursor();
3674            let mut depth = 1;
3675            let mut offset = 0;
3676            loop {
3677                let tok = input.look_ahead(offset);
3678                match &tok.kind {
3679                    TokenKind::LParen => depth += 1,
3680                    TokenKind::RParen => {
3681                        depth -= 1;
3682                        if depth == 0 {
3683                            break;
3684                        }
3685                    }
3686                    TokenKind::Eof => break,
3687                    _ => {}
3688                }
3689                offset += 1;
3690            }
3691            // offset points to ')' position relative to current cursor
3692            // Check if token AFTER ')' is '->'
3693            if input.look_ahead(offset + 1).kind == TokenKind::Arrow {
3694                // Parse lambda params (cursor is after '('; parse_lambda_params_after_lparen
3695                // handles parsing until ')')
3696                let params = parse_lambda_params_after_lparen(input)?;
3697                let arrow_span = input.peek().span;
3698                input.next();
3699                let body = parse_lambda_body(input)?;
3700                return Ok(Expr::Lambda(LambdaExpr {
3701                    params,
3702                    arrow_span,
3703                    body,
3704                    span: open.join(input.peek().span),
3705                }));
3706            }
3707            input.set_cursor(lambda_saved);
3708        }
3709
3710        // Parenthesized expression
3711        let expr = parse_expression(input)?;
3712        input.expect(TokenKind::RParen)?;
3713        let close = input.peek().span;
3714        return Ok(Expr::Paren {
3715            paren_span: (open, close),
3716            expr: Box::new(expr),
3717        });
3718    }
3719
3720    match &input.peek().kind {
3721        TokenKind::IntegerLit(v) => {
3722            let value = v.clone();
3723            let sp = input.peek().span;
3724            input.next();
3725            Ok(Expr::Literal(Lit::Int(IntLit { value, span: sp })))
3726        }
3727        TokenKind::FloatLit(v) => {
3728            let value = v.clone();
3729            let sp = input.peek().span;
3730            input.next();
3731            Ok(Expr::Literal(Lit::Float(FloatLit { value, span: sp })))
3732        }
3733        TokenKind::BoolLit(b) => {
3734            let value = *b;
3735            let sp = input.peek().span;
3736            input.next();
3737            Ok(Expr::Literal(Lit::Bool(BoolLit { value, span: sp })))
3738        }
3739        TokenKind::CharLit(v) => {
3740            let value = v.clone();
3741            let sp = input.peek().span;
3742            input.next();
3743            Ok(Expr::Literal(Lit::Char(CharLit { value, span: sp })))
3744        }
3745        TokenKind::StringLit(v) => {
3746            let value = v.clone();
3747            let sp = input.peek().span;
3748            input.next();
3749            Ok(Expr::Literal(Lit::Str(StrLit { value, span: sp })))
3750        }
3751        TokenKind::NullLit => {
3752            let sp = input.peek().span;
3753            input.next();
3754            Ok(Expr::Literal(Lit::Null(NullLit { span: sp })))
3755        }
3756        TokenKind::This => {
3757            let sp = input.peek().span;
3758            input.next();
3759            Ok(Expr::This(sp))
3760        }
3761        TokenKind::Super => {
3762            let sp = input.peek().span;
3763            input.next();
3764            Ok(Expr::Super(sp))
3765        }
3766        TokenKind::New => parse_new_expr(input),
3767        TokenKind::Switch => parse_switch_expr(input),
3768        TokenKind::LBrace => Ok(Expr::ArrayInit(parse_array_init(input)?)),
3769        _ => {
3770            // Check for identifier (possibly with method reference)
3771            // Also allow primitive type keywords and void as identifiers for .class expressions
3772            if input.is_any_ident()
3773                || is_contextual_type_keyword(&input.peek().kind)
3774                || is_primitive_type_token(&input.peek().kind)
3775                || input.is(&TokenKind::Void)
3776            {
3777                let ident = input.parse_ident()?;
3778                // Check for single-param lambda: `x -> expr`
3779                if input.is(&TokenKind::Arrow) {
3780                    let ident_span = ident.span;
3781                    let arrow_span = input.peek().span;
3782                    input.next();
3783                    let body = parse_lambda_body(input)?;
3784                    let end = body.span();
3785                    return Ok(Expr::Lambda(LambdaExpr {
3786                        params: LambdaParams::Single(ident),
3787                        arrow_span,
3788                        body,
3789                        span: ident_span.join(end),
3790                    }));
3791                }
3792                // Check for type arguments followed by :: (method reference with type args)
3793                // e.g., Collection<T>::add, Class<?>[]::new
3794                if input.is(&TokenKind::Lt) {
3795                    let saved = input.save_state();
3796                    if let Ok(type_args) = parse_type_arguments(input) {
3797                        // Skip optional array dims [] between type args and ::
3798                        // e.g., Class<?>[]::new has [] between > and ::
3799                        while input.is(&TokenKind::LBracket)
3800                            && input.look_ahead(1).kind == TokenKind::RBracket
3801                        {
3802                            input.next(); // [
3803                            input.next(); // ]
3804                        }
3805                        if input.is(&TokenKind::ColonColon) {
3806                            let colon_colon_span = input.peek().span;
3807                            input.next();
3808                            let type_args2 = parse_optional_type_arguments(input);
3809                            let method_name = if input.is(&TokenKind::New) {
3810                                let name = Ident::new("new".to_string(), input.peek().span);
3811                                input.next();
3812                                name
3813                            } else {
3814                                input.parse_ident()?
3815                            };
3816                            let path = Path {
3817                                segments: vec![PathSegment {
3818                                    ident,
3819                                    args: Some(type_args),
3820                                }],
3821                                span: span.join(input.peek().span),
3822                            };
3823                            return Ok(Expr::MethodRef(MethodRefExpr {
3824                                target: MethodRefTarget::Type(path),
3825                                colon_colon_span,
3826                                type_args: type_args2,
3827                                method_name,
3828                            }));
3829                        }
3830                    }
3831                    input.restore_state(saved);
3832                }
3833                Ok(Expr::Ident(ident))
3834            } else {
3835                Err(crate::error::Error::new(span, "expected expression"))
3836            }
3837        }
3838    }
3839}
3840
3841fn parse_lambda_params_after_lparen(input: &ParseStream) -> Result<LambdaParams> {
3842    let open = input.peek().span;
3843    let mut params = Vec::new();
3844    let mut idents = Vec::new();
3845
3846    while !input.is(&TokenKind::RParen) && !input.is_empty() {
3847        let saved = input.cursor();
3848        // Try to parse as typed parameter: Type name
3849        if let Ok(ty) = parse_type(input) {
3850            if input.is_any_ident() {
3851                let name = input.parse_ident()?;
3852                params.push(LambdaParam {
3853                    modifiers: vec![],
3854                    ty,
3855                    name,
3856                });
3857                if !input.eat(&TokenKind::Comma) {
3858                    break;
3859                }
3860                continue;
3861            }
3862            input.set_cursor(saved);
3863        } else {
3864            input.set_cursor(saved);
3865        }
3866        // Parse as inferred parameter: just an ident
3867        let ident = input.parse_ident()?;
3868        idents.push(ident);
3869        if !input.eat(&TokenKind::Comma) {
3870            break;
3871        }
3872    }
3873
3874    input.expect(TokenKind::RParen)?;
3875    let close = input.peek().span;
3876
3877    if !params.is_empty() && idents.is_empty() {
3878        Ok(LambdaParams::List {
3879            paren_span: (open, close),
3880            params,
3881        })
3882    } else if params.is_empty() && !idents.is_empty() {
3883        Ok(LambdaParams::IdentList {
3884            paren_span: (open, close),
3885            idents,
3886        })
3887    } else if params.is_empty() && idents.is_empty() {
3888        Ok(LambdaParams::IdentList {
3889            paren_span: (open, close),
3890            idents: vec![],
3891        })
3892    } else {
3893        Ok(LambdaParams::IdentList {
3894            paren_span: (open, close),
3895            idents,
3896        })
3897    }
3898}
3899
3900fn parse_lambda_body(input: &ParseStream) -> Result<LambdaBody> {
3901    if input.is(&TokenKind::LBrace) {
3902        Ok(LambdaBody::Block(parse_block(input, Vec::new())?))
3903    } else {
3904        Ok(LambdaBody::Expr(Box::new(parse_expression(input)?)))
3905    }
3906}
3907
3908fn parse_new_expr(input: &ParseStream) -> Result<Expr> {
3909    let new_span = input.peek().span;
3910    input.expect(TokenKind::New)?;
3911    let type_args = parse_optional_type_arguments(input);
3912
3913    // Parse the element/base type WITHOUT consuming array dimensions
3914    let annotations = parse_type_annotations(input);
3915    let base_type = if is_primitive_type_token(&input.peek().kind) {
3916        let prim = parse_primitive_type(input)?;
3917        Type::Primitive(prim)
3918    } else if input.is_any_ident() || is_contextual_type_keyword(&input.peek().kind) {
3919        let path = parse_path(input)?;
3920        Type::Reference(ReferenceType::ClassOrInterfaceType(ClassOrInterfaceType {
3921            path,
3922            annotations_prefix: annotations,
3923        }))
3924    } else {
3925        return Err(crate::error::Error::new(
3926            new_span,
3927            "expected type after new",
3928        ));
3929    };
3930
3931    // Check for array creation: new Type[expr] or new Type[]
3932    if input.is(&TokenKind::LBracket) {
3933        let mut dim_exprs = Vec::new();
3934        let mut dims = Vec::new();
3935
3936        while input.is(&TokenKind::LBracket) {
3937            let open = input.peek().span;
3938            input.next();
3939            if input.is(&TokenKind::RBracket) {
3940                input.next();
3941                let close = input.peek().span;
3942                dims.push(ArrayDim {
3943                    bracket_span: (open, close),
3944                    annotations: Vec::new(),
3945                });
3946            } else {
3947                let anns = parse_type_annotations(input);
3948                let expr = parse_expression(input)?;
3949                input.expect(TokenKind::RBracket)?;
3950                let close = input.peek().span;
3951                dim_exprs.push(ArrayDimExpr {
3952                    annotations: anns,
3953                    bracket_span: (open, close),
3954                    expr: Box::new(expr),
3955                });
3956            }
3957        }
3958
3959        let initializer = if input.is(&TokenKind::LBrace) {
3960            Some(parse_array_init(input)?)
3961        } else {
3962            None
3963        };
3964
3965        return Ok(Expr::ArrayNew(ArrayNewExpr {
3966            new_span,
3967            elem_type: base_type,
3968            dim_exprs,
3969            dims,
3970            initializer,
3971        }));
3972    }
3973
3974    // Class instantiation: new Type(args) or new Type { ... }
3975    if input.is(&TokenKind::LParen) || input.is(&TokenKind::LBrace) {
3976        let class_type = match &base_type {
3977            Type::Reference(ReferenceType::ClassOrInterfaceType(cit)) => cit.path.clone(),
3978            _ => {
3979                return Err(crate::error::Error::new(
3980                    input.peek().span,
3981                    "expected class type",
3982                ));
3983            }
3984        };
3985
3986        if input.is(&TokenKind::LParen) {
3987            input.expect(TokenKind::LParen)?;
3988            let open = input.peek().span;
3989            let args = input.parse_terminated(parse_expression)?;
3990            input.expect(TokenKind::RParen)?;
3991            let close = input.peek().span;
3992            let body = if input.is(&TokenKind::LBrace) {
3993                let dl = parse_class_body_decl_list(input)?;
3994                Some(dl)
3995            } else {
3996                None
3997            };
3998            return Ok(Expr::NewClass(NewClassExpr {
3999                new_span,
4000                type_args,
4001                class_type,
4002                paren_span: (open, close),
4003                args,
4004                body,
4005            }));
4006        }
4007
4008        // Anonymous class with no args
4009        let dl = parse_class_body_decl_list(input)?;
4010        let body = dl;
4011        return Ok(Expr::NewClass(NewClassExpr {
4012            new_span,
4013            type_args,
4014            class_type,
4015            paren_span: (Span::call_site(), Span::call_site()),
4016            args: Vec::new(),
4017            body: Some(body),
4018        }));
4019    }
4020
4021    Err(crate::error::Error::new(
4022        new_span,
4023        "expected type after new",
4024    ))
4025}
4026
4027fn parse_switch_expr(input: &ParseStream) -> Result<Expr> {
4028    let switch_span = input.peek().span;
4029    input.expect(TokenKind::Switch)?;
4030    input.expect(TokenKind::LParen)?;
4031    let open = input.peek().span;
4032    let selector = parse_expression(input)?;
4033    input.expect(TokenKind::RParen)?;
4034    let close = input.peek().span;
4035    input.expect(TokenKind::LBrace)?;
4036    let brace_open = input.peek().span;
4037    let mut cases = Vec::new();
4038    while !input.is(&TokenKind::RBrace) && !input.is_empty() {
4039        cases.push(parse_switch_arm(input)?);
4040    }
4041    input.expect(TokenKind::RBrace)?;
4042    let brace_close = input.peek().span;
4043    Ok(Expr::Switch(SwitchExpr {
4044        switch_span,
4045        paren_span: (open, close),
4046        selector: Box::new(selector),
4047        brace_span: (brace_open, brace_close),
4048        cases,
4049    }))
4050}
4051
4052fn parse_switch_arm(input: &ParseStream) -> Result<SwitchArm> {
4053    let labels = parse_switch_labels(input)?;
4054    let label = labels
4055        .into_iter()
4056        .next()
4057        .ok_or_else(|| crate::error::Error::new(input.peek().span, "expected case or default"))?;
4058
4059    if input.eat(&TokenKind::Arrow) {
4060        let arrow = input.peek().span;
4061        if input.is(&TokenKind::Throw) {
4062            let _throw_span = input.peek().span;
4063            input.next();
4064            let expr = parse_expression(input)?;
4065            input.expect(TokenKind::Semicolon)?;
4066            Ok(SwitchArm::Throw(label, arrow, expr))
4067        } else if input.is(&TokenKind::LBrace) {
4068            let block = parse_block(input, Vec::new())?;
4069            Ok(SwitchArm::Block(label, arrow, block))
4070        } else {
4071            let expr = parse_expression(input)?;
4072            input.expect(TokenKind::Semicolon)?;
4073            Ok(SwitchArm::Expr(label, arrow, expr))
4074        }
4075    } else {
4076        input.expect(TokenKind::Colon)?;
4077        let mut stmts = Vec::new();
4078        while !input.is_empty() {
4079            if is_switch_label_start(input) || input.is(&TokenKind::RBrace) {
4080                break;
4081            }
4082            stmts.push(parse_statement(input)?);
4083        }
4084        Ok(SwitchArm::Colon(label, stmts))
4085    }
4086}
4087
4088// ============================================================================
4089// Pattern
4090// ============================================================================
4091
4092fn parse_pattern(input: &ParseStream) -> Result<Pattern> {
4093    let annotations = parse_annotations(input)?;
4094
4095    // Try record pattern: Type(Component1, Component2)
4096    // or type pattern: Type name
4097    let ty = parse_type(input)?;
4098
4099    if input.is(&TokenKind::LParen) {
4100        // Record pattern
4101        input.next();
4102        let mut components = Vec::new();
4103        while !input.is(&TokenKind::RParen) && !input.is_empty() {
4104            components.push(parse_pattern(input)?);
4105            input.eat(&TokenKind::Comma);
4106        }
4107        input.expect(TokenKind::RParen)?;
4108        let start = annotations.first().map(|a| a.span()).unwrap_or(ty.span());
4109        let end = input.peek().span;
4110        Ok(Pattern::RecordPattern(RecordPattern {
4111            record_type: ty,
4112            components,
4113            span: start.join(end),
4114        }))
4115    } else {
4116        // Type pattern
4117        let name = input.parse_ident().ok();
4118        let start = annotations.first().map(|a| a.span()).unwrap_or(ty.span());
4119        let end = name.as_ref().map(|n| n.span()).unwrap_or(ty.span());
4120        Ok(Pattern::TypePattern(TypePattern {
4121            annotations,
4122            ty,
4123            name,
4124            span: start.join(end),
4125        }))
4126    }
4127}