1use crate::{kind::JavaSyntaxKind, language::JavaLanguage, lexer::JavaLexer};
2use oak_core::{
3 GreenNode, OakError, TextEdit, TokenType,
4 parser::{
5 ParseCache, Parser, ParserState,
6 pratt::{Associativity, Pratt, PrattParser, binary},
7 },
8 source::Source,
9};
10
11pub(crate) type State<'a, S> = ParserState<'a, JavaLanguage, S>;
12
13pub struct JavaParser<'config> {
14 pub(crate) config: &'config JavaLanguage,
15}
16
17impl<'config> Pratt<JavaLanguage> for JavaParser<'config> {
18 fn primary<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> &'a GreenNode<'a, JavaLanguage> {
19 use crate::kind::JavaSyntaxKind::*;
20 let cp = state.checkpoint();
21 match state.peek_kind() {
22 Some(Identifier) => {
23 state.bump();
24 state.finish_at(cp, Identifier.into())
25 }
26 Some(IntegerLiteral) | Some(FloatingPointLiteral) | Some(BooleanLiteral) | Some(CharacterLiteral) | Some(StringLiteral) | Some(NullLiteral) => {
27 state.bump();
28 state.finish_at(cp, CompilationUnit.into()) }
30 Some(LeftParen) => {
31 state.bump();
32 PrattParser::parse(state, 0, self);
33 state.expect(RightParen).ok();
34 state.finish_at(cp, CompilationUnit.into())
35 }
36 _ => {
37 state.bump();
38 state.finish_at(cp, Error.into())
39 }
40 }
41 }
42
43 fn prefix<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> &'a GreenNode<'a, JavaLanguage> {
44 self.primary(state)
45 }
46
47 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>> {
48 use crate::kind::JavaSyntaxKind::*;
49 let kind = state.peek_kind()?;
50
51 let (prec, assoc) = match kind {
52 Assign | PlusEquals | MinusEquals | AsteriskEquals | SlashEquals | PercentEquals | LeftShiftEquals | RightShiftEquals | UnsignedRightShiftEquals | AmpersandEquals | PipeEquals | CaretEquals => (1, Associativity::Right),
53 PipePipe => (2, Associativity::Left),
54 AmpersandAmpersand => (3, Associativity::Left),
55 Equals | BangEquals | LessThan | GreaterThan | LessThanEquals | GreaterThanEquals => (4, Associativity::Left),
56 Plus | Minus => (10, Associativity::Left),
57 Asterisk | Slash | Percent => (11, Associativity::Left),
58 LeftParen | Dot => (15, Associativity::Left),
59 _ => return None,
60 };
61
62 if prec < min_precedence {
63 return None;
64 }
65
66 match kind {
67 LeftParen => {
68 let cp = state.checkpoint();
69 state.push_child(left);
70 state.expect(LeftParen).ok();
71 while state.not_at_end() && !state.at(RightParen) {
72 state.advance();
73 }
74 state.expect(RightParen).ok();
75 Some(state.finish_at(cp, CompilationUnit.into()))
76 }
77 Dot => {
78 let cp = state.checkpoint();
79 state.push_child(left);
80 state.expect(Dot).ok();
81 state.expect(Identifier).ok();
82 Some(state.finish_at(cp, CompilationUnit.into()))
83 }
84 _ => Some(binary(state, left, kind, prec, assoc, CompilationUnit.into(), |s, p| PrattParser::parse(s, p, self))),
85 }
86 }
87}
88
89impl<'config> JavaParser<'config> {
90 pub fn new(config: &'config JavaLanguage) -> Self {
91 Self { config }
92 }
93
94 fn parse_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
95 use crate::kind::JavaSyntaxKind::*;
96 match state.peek_kind() {
97 Some(Public) | Some(Private) | Some(Protected) | Some(Static) | Some(Final) | Some(Class) | Some(Interface) | Some(Enum) => self.parse_declaration(state)?,
98 Some(If) => self.parse_if_statement(state)?,
99 Some(While) => self.parse_while_statement(state)?,
100 Some(For) => self.parse_for_statement(state)?,
101 Some(Return) => self.parse_return_statement(state)?,
102 Some(LeftBrace) => self.parse_block_statement(state)?,
103 Some(Package) => self.parse_package_declaration(state)?,
104 Some(Import) => self.parse_import_declaration(state)?,
105 _ => {
106 PrattParser::parse(state, 0, self);
107 state.eat(Semicolon);
108 }
109 }
110 Ok(())
111 }
112
113 fn parse_package_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
114 use crate::kind::JavaSyntaxKind::*;
115 state.expect(Package).ok();
116 state.advance_until(Semicolon);
117 state.eat(Semicolon);
118 Ok(())
119 }
120
121 fn parse_import_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
122 use crate::kind::JavaSyntaxKind::*;
123 state.expect(Import).ok();
124 state.advance_until(Semicolon);
125 state.eat(Semicolon);
126 Ok(())
127 }
128
129 fn parse_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
130 use crate::kind::JavaSyntaxKind::*;
131 while state.not_at_end() && matches!(state.peek_kind(), Some(Public) | Some(Private) | Some(Protected) | Some(Static) | Some(Final) | Some(Abstract)) {
133 state.bump();
134 }
135
136 match state.peek_kind() {
137 Some(Class) => self.parse_class_declaration(state)?,
138 Some(Interface) => self.parse_interface_declaration(state)?,
139 Some(Enum) => self.parse_enum_declaration(state)?,
140 _ => {
141 state.advance_until(Semicolon);
143 state.eat(Semicolon);
144 }
145 }
146 Ok(())
147 }
148
149 fn parse_class_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
150 use crate::kind::JavaSyntaxKind::*;
151 state.expect(Class).ok();
152 state.expect(Identifier).ok();
153 if state.eat(Extends) {
154 state.expect(Identifier).ok();
155 }
156 if state.eat(Implements) {
157 while state.not_at_end() && !state.at(LeftBrace) {
158 state.advance();
159 }
160 }
161 self.parse_block_statement(state)?;
162 Ok(())
163 }
164
165 fn parse_interface_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
166 use crate::kind::JavaSyntaxKind::*;
167 state.expect(Interface).ok();
168 state.expect(Identifier).ok();
169 self.parse_block_statement(state)?;
170 Ok(())
171 }
172
173 fn parse_enum_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
174 use crate::kind::JavaSyntaxKind::*;
175 state.expect(Enum).ok();
176 state.expect(Identifier).ok();
177 self.parse_block_statement(state)?;
178 Ok(())
179 }
180
181 fn parse_if_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
182 state.bump(); state.expect(crate::kind::JavaSyntaxKind::LeftParen).ok();
184 PrattParser::parse(state, 0, self);
185 state.expect(crate::kind::JavaSyntaxKind::RightParen).ok();
186 self.parse_statement(state)?;
187 if state.eat(crate::kind::JavaSyntaxKind::Else) {
188 self.parse_statement(state)?;
189 }
190 Ok(())
191 }
192
193 fn parse_while_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
194 state.bump(); state.expect(crate::kind::JavaSyntaxKind::LeftParen).ok();
196 PrattParser::parse(state, 0, self);
197 state.expect(crate::kind::JavaSyntaxKind::RightParen).ok();
198 self.parse_statement(state)?;
199 Ok(())
200 }
201
202 fn parse_for_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
203 state.bump(); state.expect(crate::kind::JavaSyntaxKind::LeftParen).ok();
205 PrattParser::parse(state, 0, self);
206 state.expect(crate::kind::JavaSyntaxKind::RightParen).ok();
207 self.parse_statement(state)?;
208 Ok(())
209 }
210
211 fn parse_block_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
212 state.expect(crate::kind::JavaSyntaxKind::LeftBrace).ok();
213 while state.not_at_end() && !state.at(crate::kind::JavaSyntaxKind::RightBrace) {
214 self.parse_statement(state)?;
215 }
216 state.expect(crate::kind::JavaSyntaxKind::RightBrace).ok();
217 Ok(())
218 }
219
220 fn parse_return_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
221 state.bump(); if !state.at(crate::kind::JavaSyntaxKind::Semicolon) && !state.at(crate::kind::JavaSyntaxKind::RightBrace) {
223 PrattParser::parse(state, 0, self);
224 }
225 state.eat(crate::kind::JavaSyntaxKind::Semicolon);
226 Ok(())
227 }
228}
229
230impl<'config> Parser<JavaLanguage> for JavaParser<'config> {
231 fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<JavaLanguage>) -> oak_core::ParseOutput<'a, JavaLanguage> {
232 let lexer = JavaLexer::new(self.config);
233 oak_core::parser::parse_with_lexer(&lexer, text, edits, cache, |state| {
234 let checkpoint = state.checkpoint();
235 while state.not_at_end() {
236 if state.current().map(|t| t.kind.is_ignored()).unwrap_or(false) {
237 state.advance();
238 continue;
239 }
240 self.parse_statement(state).ok();
241 }
242 Ok(state.finish_at(checkpoint, JavaSyntaxKind::CompilationUnit.into()))
243 })
244 }
245}