Skip to main content

oak_java/parser/
mod.rs

1use oak_core::TokenType;
2
3/// Java element types.
4pub mod element_type;
5
6use crate::{
7    language::JavaLanguage,
8    lexer::{JavaLexer, token_type::JavaTokenType},
9    parser::element_type::JavaElementType,
10};
11use oak_core::{
12    GreenNode, OakError, TextEdit,
13    parser::{
14        ParseCache, Parser, ParserState,
15        pratt::{Associativity, Pratt, PrattParser, binary},
16    },
17    source::Source,
18};
19
20pub(crate) type State<'a, S> = ParserState<'a, JavaLanguage, S>;
21
22/// Java parser.
23pub struct JavaParser<'config> {
24    /// Parser configuration.
25    pub(crate) config: &'config JavaLanguage,
26}
27
28impl<'config> Pratt<JavaLanguage> for JavaParser<'config> {
29    fn primary<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> &'a GreenNode<'a, JavaLanguage> {
30        use crate::lexer::token_type::JavaTokenType::*;
31        self.skip_trivia(state);
32        let cp = state.checkpoint();
33        match state.peek_kind() {
34            Some(Identifier) => {
35                state.bump();
36                state.finish_at(cp, JavaElementType::Identifier)
37            }
38            Some(IntegerLiteral) | Some(FloatingPointLiteral) | Some(BooleanLiteral) | Some(CharacterLiteral) | Some(StringLiteral) | Some(NullLiteral) => {
39                state.bump();
40                state.finish_at(cp, JavaElementType::LiteralExpression)
41            }
42            Some(LeftParen) => {
43                state.bump();
44                PrattParser::parse(state, 0, self);
45                state.expect(RightParen).ok();
46                state.finish_at(cp, JavaElementType::ParenthesizedExpression)
47            }
48            Some(New) => {
49                state.bump(); // new
50                self.skip_trivia(state);
51                self.parse_type(state).ok();
52                self.skip_trivia(state);
53                if state.at(LeftBracket) {
54                    // Array creation
55                    while state.at(LeftBracket) {
56                        state.bump();
57                        self.skip_trivia(state);
58                        if !state.at(RightBracket) {
59                            PrattParser::parse(state, 0, self);
60                        }
61                        self.skip_trivia(state);
62                        state.expect(RightBracket).ok();
63                        self.skip_trivia(state)
64                    }
65                    state.finish_at(cp, JavaElementType::ArrayCreation)
66                }
67                else if state.at(LeftParen) {
68                    // Object creation
69                    state.bump();
70                    self.skip_trivia(state);
71                    while state.not_at_end() && !state.at(RightParen) {
72                        PrattParser::parse(state, 0, self);
73                        self.skip_trivia(state);
74                        if !state.eat(Comma) {
75                            break;
76                        }
77                        self.skip_trivia(state)
78                    }
79                    state.expect(RightParen).ok();
80                    state.finish_at(cp, JavaElementType::MethodCall) // Reuse MethodCall for constructor for now
81                }
82                else {
83                    state.finish_at(cp, JavaElementType::Error)
84                }
85            }
86            _ => {
87                state.bump();
88                state.finish_at(cp, JavaElementType::Error)
89            }
90        }
91    }
92
93    fn prefix<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> &'a GreenNode<'a, JavaLanguage> {
94        use crate::lexer::token_type::JavaTokenType::*;
95        self.skip_trivia(state);
96        let cp = state.checkpoint();
97        match state.peek_kind() {
98            Some(Bang) | Some(Tilde) | Some(Plus) | Some(Minus) | Some(PlusPlus) | Some(MinusMinus) => {
99                state.bump();
100                PrattParser::parse(state, 14, self); // Prefix operators have high precedence
101                state.finish_at(cp, JavaElementType::UnaryExpression)
102            }
103            Some(LeftParen) => {
104                // Try to parse as Cast: (Type) Expr
105                // For now, a simple heuristic: if it looks like (Identifier), it might be a cast
106                // But this is ambiguous with parenthesized expressions.
107                // Standard Java parser looks ahead.
108                // We'll try to parse a type inside.
109                let snapshot = state.checkpoint();
110                state.bump(); // (
111                self.skip_trivia(state);
112                if self.parse_type(state).is_ok() {
113                    self.skip_trivia(state);
114                    if state.eat(RightParen) {
115                        self.skip_trivia(state);
116                        // It's a cast if we have an expression following it
117                        PrattParser::parse(state, 13, self); // Precedence for cast
118                        state.finish_at(cp, JavaElementType::CastExpression)
119                    }
120                    else {
121                        state.restore(snapshot);
122                        self.primary(state)
123                    }
124                }
125                else {
126                    state.restore(snapshot);
127                    self.primary(state)
128                }
129            }
130            _ => self.primary(state),
131        }
132    }
133
134    fn infix<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, left: &'a GreenNode<'a, JavaLanguage>, min_precedence: u8) -> Option<&'a GreenNode<'a, JavaLanguage>> {
135        use crate::lexer::token_type::JavaTokenType::*;
136        self.skip_trivia(state);
137        let kind = state.peek_kind()?;
138        eprintln!("DEBUG: Parser infix peeking {:?}", kind);
139
140        let (prec, assoc) = match kind {
141            Assign | PlusEquals | MinusEquals | AsteriskEquals | SlashEquals | PercentEquals | LeftShiftEquals | RightShiftEquals | UnsignedRightShiftEquals | AmpersandEquals | PipeEquals | CaretEquals => (1, Associativity::Right),
142            Question => (2, Associativity::Right),
143            PipePipe => (3, Associativity::Left),
144            AmpersandAmpersand => (4, Associativity::Left),
145            Pipe => (5, Associativity::Left),
146            Caret => (6, Associativity::Left),
147            Ampersand => (7, Associativity::Left),
148            Equals | BangEquals => (8, Associativity::Left),
149            LessThan | GreaterThan | LessThanEquals | GreaterThanEquals | Instanceof => (9, Associativity::Left),
150            LeftShift | RightShift | UnsignedRightShift => (10, Associativity::Left),
151            Plus | Minus => (11, Associativity::Left),
152            Asterisk | Slash | Percent => (12, Associativity::Left),
153            PlusPlus | MinusMinus => (15, Associativity::Left), // Postfix
154            LeftParen | Dot | LeftBracket => (16, Associativity::Left),
155            _ => return None,
156        };
157
158        if prec < min_precedence {
159            return None;
160        }
161
162        match kind {
163            PlusPlus | MinusMinus => {
164                let cp = state.checkpoint_before(left);
165                state.bump();
166                Some(state.finish_at(cp, JavaElementType::PostfixExpression))
167            }
168            Assign | PlusEquals | MinusEquals | AsteriskEquals | SlashEquals | PercentEquals | LeftShiftEquals | RightShiftEquals | UnsignedRightShiftEquals | AmpersandEquals | PipeEquals | CaretEquals => {
169                Some(binary(state, left, kind, prec, assoc, JavaElementType::AssignmentExpression.into(), |s, p| PrattParser::parse(s, p, self)))
170            }
171            Question => {
172                let cp = state.checkpoint_before(left);
173                state.bump(); // ?
174                self.skip_trivia(state);
175                PrattParser::parse(state, 0, self); // then branch
176                self.skip_trivia(state);
177                state.expect(Colon).ok(); // :
178                self.skip_trivia(state);
179                PrattParser::parse(state, prec, self); // else branch (right assoc)
180                Some(state.finish_at(cp, JavaElementType::TernaryExpression))
181            }
182            LeftParen => {
183                let cp = state.checkpoint_before(left);
184                state.expect(LeftParen).ok();
185                self.skip_trivia(state);
186                while state.not_at_end() && !state.at(RightParen) {
187                    PrattParser::parse(state, 0, self);
188                    self.skip_trivia(state);
189                    if state.eat(Comma) {
190                        self.skip_trivia(state);
191                        continue;
192                    }
193                }
194                state.expect(RightParen).ok();
195                Some(state.finish_at(cp, JavaElementType::MethodCall))
196            }
197            Dot => {
198                let cp = state.checkpoint_before(left);
199                state.expect(Dot).ok();
200                self.skip_trivia(state);
201                state.expect(Identifier).ok();
202                Some(state.finish_at(cp, JavaElementType::MemberSelect))
203            }
204            LeftBracket => {
205                let cp = state.checkpoint_before(left);
206                state.expect(LeftBracket).ok();
207                self.skip_trivia(state);
208                PrattParser::parse(state, 0, self);
209                self.skip_trivia(state);
210                state.expect(RightBracket).ok();
211                Some(state.finish_at(cp, JavaElementType::ArrayAccess))
212            }
213            _ => Some(binary(state, left, kind, prec, assoc, JavaElementType::BinaryExpression.into(), |s, p| PrattParser::parse(s, p, self))),
214        }
215    }
216}
217
218impl<'config> JavaParser<'config> {
219    /// Creates a new `JavaParser`.
220    pub fn new(config: &'config JavaLanguage) -> Self {
221        Self { config }
222    }
223
224    fn parse_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
225        use crate::lexer::token_type::JavaTokenType::*;
226        self.skip_trivia(state);
227        let cp = state.checkpoint();
228        let pk = state.peek_kind();
229        match pk {
230            Some(Public) | Some(Private) | Some(Protected) | Some(Static) | Some(Final) | Some(Abstract) | Some(Class) | Some(Interface) | Some(Enum) | Some(Struct) | Some(Record) => self.parse_declaration(state)?,
231            Some(Int) | Some(Boolean) | Some(Void) | Some(Long) | Some(Float) | Some(Double) | Some(Char) | Some(Byte) | Some(Short) => {
232                self.parse_variable_declaration(state)?;
233                state.finish_at(cp, JavaElementType::VariableDeclaration);
234            }
235            Some(Identifier) => {
236                // Could be a type name for a variable declaration, or an expression
237                let snapshot = state.checkpoint();
238                if self.parse_type(state).is_ok() {
239                    self.skip_trivia(state);
240                    if state.at(Identifier) {
241                        state.restore(snapshot);
242                        self.parse_variable_declaration(state)?;
243                        state.finish_at(cp, JavaElementType::VariableDeclaration);
244                    }
245                    else {
246                        state.restore(snapshot);
247                        PrattParser::parse(state, 0, self);
248                        self.skip_trivia(state);
249                        state.eat(Semicolon);
250                        state.finish_at(cp, JavaElementType::ExpressionStatement);
251                    }
252                }
253                else {
254                    state.restore(snapshot);
255                    PrattParser::parse(state, 0, self);
256                    self.skip_trivia(state);
257                    state.eat(Semicolon);
258                    state.finish_at(cp, JavaElementType::ExpressionStatement);
259                }
260            }
261            Some(If) => {
262                self.parse_if_statement(state)?;
263                state.finish_at(cp, JavaElementType::IfStatement);
264            }
265            Some(While) => {
266                self.parse_while_statement(state)?;
267                state.finish_at(cp, JavaElementType::WhileStatement);
268            }
269            Some(Do) => {
270                self.parse_do_while_statement(state)?;
271                state.finish_at(cp, JavaElementType::DoWhileStatement);
272            }
273            Some(For) => {
274                self.parse_for_statement(state)?;
275                state.finish_at(cp, JavaElementType::ForStatement);
276            }
277            Some(Switch) => {
278                self.parse_switch_statement(state)?;
279                state.finish_at(cp, JavaElementType::SwitchStatement);
280            }
281            Some(Return) => {
282                self.parse_return_statement(state)?;
283                state.finish_at(cp, JavaElementType::ReturnStatement);
284            }
285            Some(Break) => {
286                state.bump(); // break
287                state.eat(Semicolon);
288                state.finish_at(cp, JavaElementType::Break);
289            }
290            Some(Continue) => {
291                state.bump(); // continue
292                state.eat(Semicolon);
293                state.finish_at(cp, JavaElementType::Continue);
294            }
295            Some(LeftBrace) => {
296                self.parse_block_statement(state)?;
297            }
298            Some(Try) => {
299                state.bump(); // try
300                self.parse_block_statement(state)?;
301                self.skip_trivia(state);
302                while state.at(Catch) {
303                    let c_cp = state.checkpoint();
304                    state.bump(); // catch
305                    self.skip_trivia(state);
306                    state.expect(LeftParen).ok();
307                    self.skip_trivia(state);
308                    // Catch parameter: Type Name
309                    let p_cp = state.checkpoint();
310                    self.parse_type(state).ok();
311                    self.skip_trivia(state);
312                    state.expect(Identifier).ok();
313                    state.finish_at(p_cp, JavaElementType::Parameter);
314                    self.skip_trivia(state);
315                    state.expect(RightParen).ok();
316                    self.skip_trivia(state);
317                    self.parse_block_statement(state)?;
318                    state.finish_at(c_cp, JavaElementType::CatchClause);
319                    self.skip_trivia(state);
320                }
321                if state.eat(Finally) {
322                    self.skip_trivia(state);
323                    self.parse_block_statement(state)?;
324                }
325                state.finish_at(cp, JavaElementType::TryStatement);
326            }
327            Some(Throw) => {
328                state.bump(); // throw
329                self.skip_trivia(state);
330                PrattParser::parse(state, 0, self);
331                self.skip_trivia(state);
332                state.eat(Semicolon);
333                state.finish_at(cp, JavaElementType::ThrowStatement);
334            }
335            Some(Package) => {
336                self.parse_package_declaration(state)?;
337            }
338            Some(Import) => {
339                self.parse_import_declaration(state)?;
340            }
341            _ => {
342                PrattParser::parse(state, 0, self);
343                self.skip_trivia(state);
344                state.eat(Semicolon);
345                state.finish_at(cp, JavaElementType::ExpressionStatement);
346            }
347        }
348        Ok(())
349    }
350
351    fn skip_trivia<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
352        while let Some(kind) = state.peek_kind() {
353            if kind.is_ignored() { state.bump() } else { break }
354        }
355    }
356
357    fn parse_type<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
358        use crate::lexer::token_type::JavaTokenType::*;
359        self.skip_trivia(state);
360        let cp = state.checkpoint();
361        match state.peek_kind() {
362            Some(Identifier) | Some(Int) | Some(Boolean) | Some(Void) | Some(Long) | Some(Float) | Some(Double) | Some(Char) | Some(Byte) | Some(Short) => state.bump(),
363            _ => {
364                // Return error?
365            }
366        }
367        self.skip_trivia(state);
368        while state.at(Dot) {
369            state.bump();
370            self.skip_trivia(state);
371            state.expect(Identifier).ok();
372            self.skip_trivia(state)
373        }
374        while state.at(LeftBracket) {
375            state.bump();
376            self.skip_trivia(state);
377            state.expect(RightBracket).ok();
378            self.skip_trivia(state)
379        }
380        state.finish_at(cp, JavaElementType::Identifier);
381        Ok(())
382    }
383
384    fn parse_package_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
385        use crate::lexer::token_type::JavaTokenType::*;
386        let cp = state.checkpoint();
387        state.expect(Package).ok();
388        self.skip_trivia(state);
389        while state.not_at_end() && !state.at(Semicolon) {
390            if state.at(Identifier) || state.at(Dot) {
391                state.bump()
392            }
393            else {
394                break;
395            }
396            self.skip_trivia(state)
397        }
398        state.eat(Semicolon);
399        state.finish_at(cp, JavaElementType::Package);
400        Ok(())
401    }
402
403    fn parse_import_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
404        use crate::lexer::token_type::JavaTokenType::*;
405        let cp = state.checkpoint();
406        state.expect(Import).ok();
407        self.skip_trivia(state);
408        if state.eat(Static) {
409            self.skip_trivia(state)
410        }
411        while state.not_at_end() && !state.at(Semicolon) {
412            if state.at(Identifier) || state.at(Dot) || state.at(Asterisk) {
413                state.bump()
414            }
415            else {
416                break;
417            }
418            self.skip_trivia(state)
419        }
420        state.eat(Semicolon);
421        state.finish_at(cp, JavaElementType::Import);
422        Ok(())
423    }
424
425    fn parse_annotation<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
426        use crate::lexer::token_type::JavaTokenType::*;
427        let cp = state.checkpoint();
428        state.expect(At).ok();
429        self.skip_trivia(state);
430        self.parse_type(state).ok(); // Annotation name (can be a path)
431        self.skip_trivia(state);
432        if state.eat(LeftParen) {
433            self.skip_trivia(state);
434            while state.not_at_end() && !state.at(RightParen) {
435                PrattParser::parse(state, 0, self);
436                self.skip_trivia(state);
437                if !state.eat(Comma) {
438                    break;
439                }
440                self.skip_trivia(state);
441            }
442            state.expect(RightParen).ok();
443        }
444        state.finish_at(cp, JavaElementType::Annotation);
445        Ok(())
446    }
447
448    fn parse_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
449        use crate::lexer::token_type::JavaTokenType::*;
450        let cp = state.checkpoint();
451        self.skip_trivia(state);
452
453        // Parse annotations
454        while state.at(At) {
455            self.parse_annotation(state)?;
456            self.skip_trivia(state);
457        }
458
459        // Handle modifiers
460        while state.not_at_end() && matches!(state.peek_kind(), Some(Public) | Some(Private) | Some(Protected) | Some(Static) | Some(Final) | Some(Abstract)) {
461            state.bump();
462            self.skip_trivia(state)
463        }
464
465        match state.peek_kind() {
466            Some(Class) => {
467                state.expect(Class).ok();
468                self.skip_trivia(state);
469                state.expect(Identifier).ok();
470                self.skip_trivia(state);
471                if state.eat(Extends) {
472                    self.skip_trivia(state);
473                    state.expect(Identifier).ok();
474                    self.skip_trivia(state)
475                }
476                if state.eat(Implements) {
477                    self.skip_trivia(state);
478                    while state.not_at_end() && !state.at(LeftBrace) {
479                        state.bump();
480                        self.skip_trivia(state)
481                    }
482                }
483                self.parse_block_statement(state)?;
484                state.finish_at(cp, JavaElementType::ClassDeclaration);
485            }
486            Some(Interface) => {
487                state.expect(Interface).ok();
488                self.skip_trivia(state);
489                state.expect(Identifier).ok();
490                self.skip_trivia(state);
491                self.parse_block_statement(state)?;
492                state.finish_at(cp, JavaElementType::InterfaceDeclaration);
493            }
494            Some(Enum) => {
495                state.expect(Enum).ok();
496                self.skip_trivia(state);
497                state.expect(Identifier).ok();
498                self.skip_trivia(state);
499                self.parse_block_statement(state)?;
500                state.finish_at(cp, JavaElementType::EnumDeclaration);
501            }
502            Some(Struct) => {
503                state.expect(Struct).ok();
504                self.skip_trivia(state);
505                state.expect(Identifier).ok();
506                self.skip_trivia(state);
507                self.parse_block_statement(state)?;
508                state.finish_at(cp, JavaElementType::StructDeclaration);
509            }
510            Some(Record) => {
511                state.expect(Record).ok();
512                self.skip_trivia(state);
513                state.expect(Identifier).ok();
514                self.skip_trivia(state);
515                self.parse_block_statement(state)?;
516                state.finish_at(cp, JavaElementType::RecordDeclaration);
517            }
518            _ => {
519                // Possibly a method or field
520                // Modifiers have been consumed, current should be the type
521                self.parse_type(state).ok();
522                self.skip_trivia(state);
523                // Consume name and wrap as Identifier node
524                let name_cp = state.checkpoint();
525                state.expect(Identifier).ok();
526                state.finish_at(name_cp, JavaElementType::Identifier);
527                self.skip_trivia(state);
528
529                if state.at(LeftParen) {
530                    // Method declaration
531                    state.bump(); // (
532                    self.skip_trivia(state);
533                    while state.not_at_end() && !state.at(RightParen) {
534                        // Simple parameter parsing: Type Name
535                        let p_cp = state.checkpoint();
536                        self.parse_type(state).ok();
537                        self.skip_trivia(state);
538                        let pn_cp = state.checkpoint();
539                        state.expect(Identifier).ok(); // Name
540                        state.finish_at(pn_cp, JavaElementType::Identifier);
541                        self.skip_trivia(state);
542                        // Handle array types []
543                        while state.at(LeftBracket) {
544                            state.bump();
545                            self.skip_trivia(state);
546                            state.expect(RightBracket).ok();
547                            self.skip_trivia(state)
548                        }
549                        state.finish_at(p_cp, JavaElementType::Parameter);
550                        if !state.eat(Comma) {
551                            break;
552                        }
553                        self.skip_trivia(state)
554                    }
555                    state.expect(RightParen).ok();
556                    self.skip_trivia(state);
557                    if state.eat(Throws) {
558                        self.skip_trivia(state);
559                        while state.not_at_end() && !state.at(LeftBrace) && !state.at(Semicolon) {
560                            let t_cp = state.checkpoint();
561                            state.expect(Identifier).ok();
562                            state.finish_at(t_cp, JavaElementType::Identifier);
563                            self.skip_trivia(state);
564                            if !state.eat(Comma) {
565                                break;
566                            }
567                            self.skip_trivia(state)
568                        }
569                    }
570                    self.skip_trivia(state);
571                    if state.at(LeftBrace) {
572                        self.parse_block_statement(state)?
573                    }
574                    else {
575                        state.eat(Semicolon);
576                    }
577                    state.finish_at(cp, JavaElementType::MethodDeclaration);
578                }
579                else {
580                    // Field declaration
581                    if state.eat(Assign) {
582                        self.skip_trivia(state);
583                        PrattParser::parse(state, 0, self);
584                    }
585                    self.skip_trivia(state);
586                    state.eat(Semicolon);
587                    state.finish_at(cp, JavaElementType::FieldDeclaration);
588                }
589            }
590        }
591        Ok(())
592    }
593
594    fn _parse_class_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
595        use crate::lexer::token_type::JavaTokenType::*;
596        let cp = state.checkpoint();
597        state.expect(Class).ok();
598        state.expect(Identifier).ok();
599        if state.eat(Extends) {
600            state.expect(Identifier).ok();
601        }
602        if state.eat(Implements) {
603            while state.not_at_end() && !state.at(LeftBrace) {
604                state.bump()
605            }
606        }
607        self.parse_block_statement(state)?;
608        state.finish_at(cp, JavaElementType::ClassDeclaration);
609        Ok(())
610    }
611
612    fn _parse_interface_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
613        use crate::lexer::token_type::JavaTokenType::*;
614        state.expect(Interface).ok();
615        state.expect(Identifier).ok();
616        self.parse_block_statement(state)?;
617        Ok(())
618    }
619
620    fn _parse_enum_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
621        use crate::lexer::token_type::JavaTokenType::*;
622        state.expect(Enum).ok();
623        state.expect(Identifier).ok();
624        self.parse_block_statement(state)?;
625        Ok(())
626    }
627
628    fn parse_if_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
629        use crate::lexer::token_type::JavaTokenType::*;
630        state.bump(); // if
631        self.skip_trivia(state);
632        state.expect(LeftParen).ok();
633        self.skip_trivia(state);
634        PrattParser::parse(state, 0, self);
635        self.skip_trivia(state);
636        state.expect(RightParen).ok();
637        self.skip_trivia(state);
638        self.parse_statement(state)?;
639        self.skip_trivia(state);
640        if state.eat(Else) {
641            self.skip_trivia(state);
642            self.parse_statement(state)?;
643        }
644        Ok(())
645    }
646
647    fn parse_while_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
648        use crate::lexer::token_type::JavaTokenType::*;
649        state.bump(); // while
650        self.skip_trivia(state);
651        state.expect(LeftParen).ok();
652        self.skip_trivia(state);
653        PrattParser::parse(state, 0, self);
654        self.skip_trivia(state);
655        state.expect(RightParen).ok();
656        self.skip_trivia(state);
657        self.parse_statement(state)?;
658        Ok(())
659    }
660
661    fn parse_do_while_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
662        use crate::lexer::token_type::JavaTokenType::*;
663        state.bump(); // do
664        self.skip_trivia(state);
665        self.parse_statement(state)?;
666        self.skip_trivia(state);
667        state.expect(While).ok();
668        self.skip_trivia(state);
669        state.expect(LeftParen).ok();
670        self.skip_trivia(state);
671        PrattParser::parse(state, 0, self);
672        self.skip_trivia(state);
673        state.expect(RightParen).ok();
674        self.skip_trivia(state);
675        state.eat(Semicolon);
676        Ok(())
677    }
678
679    fn parse_for_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
680        use crate::lexer::token_type::JavaTokenType::*;
681        state.bump(); // for
682        state.expect(LeftParen).ok();
683        self.skip_trivia(state);
684
685        // 1. Init
686        if !state.at(Semicolon) {
687            let cp = state.checkpoint();
688            let pk = state.peek_kind();
689            match pk {
690                Some(Int) | Some(Boolean) | Some(Void) | Some(Long) | Some(Float) | Some(Double) | Some(Char) | Some(Byte) | Some(Short) => {
691                    self.parse_variable_declaration(state)?;
692                    state.finish_at(cp, JavaElementType::VariableDeclaration);
693                }
694                Some(Identifier) => {
695                    let snapshot = state.checkpoint();
696                    if self.parse_type(state).is_ok() && state.at(Identifier) {
697                        state.restore(snapshot);
698                        self.parse_variable_declaration(state)?;
699                        state.finish_at(cp, JavaElementType::VariableDeclaration);
700                    }
701                    else {
702                        state.restore(snapshot);
703                        PrattParser::parse(state, 0, self);
704                    }
705                }
706                _ => {
707                    PrattParser::parse(state, 0, self);
708                }
709            }
710        }
711        state.expect(Semicolon).ok();
712        self.skip_trivia(state);
713
714        // 2. Condition
715        if !state.at(Semicolon) {
716            PrattParser::parse(state, 0, self);
717        }
718        state.expect(Semicolon).ok();
719        self.skip_trivia(state);
720
721        // 3. Update
722        if !state.at(RightParen) {
723            PrattParser::parse(state, 0, self);
724        }
725        state.expect(RightParen).ok();
726        self.skip_trivia(state);
727
728        // 4. Body
729        self.parse_statement(state)?;
730        Ok(())
731    }
732
733    fn parse_variable_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
734        use crate::lexer::token_type::JavaTokenType::*;
735        self.parse_type(state)?;
736        self.skip_trivia(state);
737        let cp = state.checkpoint();
738        state.expect(Identifier).ok();
739        state.finish_at(cp, JavaElementType::Identifier);
740        self.skip_trivia(state);
741        if state.eat(Assign) {
742            self.skip_trivia(state);
743            PrattParser::parse(state, 0, self);
744        }
745        self.skip_trivia(state);
746        state.eat(Semicolon);
747        Ok(())
748    }
749
750    fn parse_switch_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
751        use crate::lexer::token_type::JavaTokenType::*;
752        state.bump(); // switch
753        self.skip_trivia(state);
754        state.expect(LeftParen).ok();
755        self.skip_trivia(state);
756        PrattParser::parse(state, 0, self);
757        self.skip_trivia(state);
758        state.expect(RightParen).ok();
759        self.skip_trivia(state);
760        state.expect(LeftBrace).ok();
761        self.skip_trivia(state);
762        while state.not_at_end() && !state.at(RightBrace) {
763            self.skip_trivia(state);
764            let cp = state.checkpoint();
765            if state.eat(Case) {
766                self.skip_trivia(state);
767                PrattParser::parse(state, 0, self);
768                self.skip_trivia(state);
769                state.expect(Colon).ok();
770                self.skip_trivia(state);
771                while state.not_at_end() && !state.at(Case) && !state.at(Default) && !state.at(RightBrace) {
772                    self.parse_statement(state).ok();
773                    self.skip_trivia(state);
774                }
775                state.finish_at(cp, JavaElementType::SwitchCase);
776            }
777            else if state.eat(Default) {
778                self.skip_trivia(state);
779                state.expect(Colon).ok();
780                self.skip_trivia(state);
781                while state.not_at_end() && !state.at(Case) && !state.at(Default) && !state.at(RightBrace) {
782                    self.parse_statement(state).ok();
783                    self.skip_trivia(state)
784                }
785                state.finish_at(cp, JavaElementType::DefaultCase);
786            }
787            else {
788                state.bump(); // error recovery
789                self.skip_trivia(state)
790            }
791        }
792        state.expect(RightBrace).ok();
793        Ok(())
794    }
795
796    fn parse_block_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
797        let cp = state.checkpoint();
798        state.expect(JavaTokenType::LeftBrace).ok();
799        while state.not_at_end() && !state.at(JavaTokenType::RightBrace) {
800            self.skip_trivia(state);
801            if state.at(JavaTokenType::RightBrace) {
802                break;
803            }
804            self.parse_statement(state).ok();
805            self.skip_trivia(state)
806        }
807        state.expect(JavaTokenType::RightBrace).ok();
808        state.finish_at(cp, JavaElementType::BlockStatement);
809        Ok(())
810    }
811
812    fn parse_return_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
813        state.bump(); // return
814        if !state.at(JavaTokenType::Semicolon) && !state.at(JavaTokenType::RightBrace) {
815            PrattParser::parse(state, 0, self);
816        }
817        state.eat(JavaTokenType::Semicolon);
818        Ok(())
819    }
820
821    fn parse_item<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
822        self.parse_statement(state)
823    }
824}
825
826impl<'config> Parser<JavaLanguage> for JavaParser<'config> {
827    fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<JavaLanguage>) -> oak_core::parser::ParseOutput<'a, JavaLanguage> {
828        let lexer = JavaLexer::new(self.config);
829        oak_core::parser::parse_with_lexer(&lexer, text, edits, cache, |state| {
830            let checkpoint = state.checkpoint();
831            while state.not_at_end() {
832                self.parse_item(state).ok();
833            }
834            Ok(state.finish_at(checkpoint, JavaElementType::CompilationUnit))
835        })
836    }
837}