Skip to main content

oak_java/builder/
mod.rs

1use crate::{
2    ast::*,
3    language::JavaLanguage,
4    lexer::token_type::JavaTokenType,
5    parser::{JavaParser, element_type::JavaElementType},
6};
7use oak_core::{
8    GreenNode, Parser, Source, TokenType,
9    builder::{BuildOutput, Builder, BuilderCache},
10    source::TextEdit,
11    tree::red_tree::{RedNode, RedTree},
12};
13
14pub struct JavaBuilder<'config> {
15    language: &'config JavaLanguage,
16}
17
18impl<'config> JavaBuilder<'config> {
19    pub fn new(language: &'config JavaLanguage) -> Self {
20        Self { language }
21    }
22
23    fn build_root(&self, green: &GreenNode<JavaLanguage>, source: &str) -> JavaRoot {
24        let red = RedNode::new(green, 0);
25        let mut items = Vec::new();
26
27        for child in red.children() {
28            if let RedTree::Node(node) = child {
29                match node.green.kind {
30                    JavaElementType::CompilationUnit => {
31                        for sub_child in node.children() {
32                            if let RedTree::Node(sub_node) = sub_child {
33                                if let Some(item) = self.build_item(sub_node, source) {
34                                    items.push(item)
35                                }
36                            }
37                        }
38                    }
39                    _ => {
40                        if let Some(item) = self.build_item(node, source) {
41                            items.push(item)
42                        }
43                    }
44                }
45            }
46        }
47
48        JavaRoot { items }
49    }
50
51    fn build_item(&self, node: RedNode<JavaLanguage>, source: &str) -> Option<Item> {
52        match node.green.kind {
53            JavaElementType::ClassDeclaration => Some(Item::Class(self.build_class(node, source))),
54            JavaElementType::InterfaceDeclaration => Some(Item::Interface(self.build_interface(node, source))),
55            JavaElementType::EnumDeclaration => Some(Item::Enum(self.build_enum(node, source))),
56            JavaElementType::StructDeclaration => Some(Item::Struct(self.build_struct(node, source))),
57            JavaElementType::RecordDeclaration => Some(Item::Record(self.build_record(node, source))),
58            JavaElementType::Package => Some(Item::Package(PackageDeclaration { name: self.extract_path(node, source), span: node.span() })),
59            JavaElementType::Import => {
60                let mut is_static = false;
61                for child in node.children() {
62                    if let RedTree::Leaf(leaf) = child {
63                        if leaf.kind == JavaTokenType::Static {
64                            is_static = true;
65                            break;
66                        }
67                    }
68                }
69                Some(Item::Import(ImportDeclaration { path: self.extract_path(node, source), is_static, span: node.span() }))
70            }
71            _ => None,
72        }
73    }
74
75    fn extract_path(&self, node: RedNode<JavaLanguage>, source: &str) -> String {
76        let mut path = String::new();
77        for child in node.children() {
78            match child {
79                RedTree::Node(sub_node) => {
80                    let sub_path = self.extract_path(sub_node, source);
81                    if !sub_path.is_empty() {
82                        if !path.is_empty() && !sub_path.starts_with('.') {
83                            path.push('.')
84                        }
85                        path.push_str(&sub_path)
86                    }
87                }
88                RedTree::Leaf(leaf) => match leaf.kind {
89                    JavaTokenType::Identifier | JavaTokenType::Asterisk => {
90                        let text = self.get_text(leaf.span, source).trim();
91                        if !path.is_empty() && !path.ends_with('.') {
92                            path.push('.')
93                        }
94                        path.push_str(text)
95                    }
96                    JavaTokenType::Dot => {
97                        if !path.is_empty() && !path.ends_with('.') {
98                            path.push('.')
99                        }
100                    }
101                    _ => {}
102                },
103            }
104        }
105        path
106    }
107
108    fn get_text<'a>(&self, span: core::range::Range<usize>, source: &'a str) -> &'a str {
109        let start = span.start.min(source.len());
110        let end = span.end.min(source.len());
111        if start > end {
112            return "";
113        }
114        &source[start..end]
115    }
116
117    fn extract_identifier(&self, node: RedNode<JavaLanguage>, source: &str) -> String {
118        match node.green.kind {
119            JavaElementType::Identifier => return self.get_text(node.span(), source).trim().to_string(),
120            JavaElementType::MemberSelect => {
121                let mut path = String::new();
122                for child in node.children() {
123                    match child {
124                        RedTree::Node(sub_node) => path = self.extract_identifier(sub_node, source),
125                        RedTree::Leaf(leaf) => {
126                            if leaf.kind == JavaTokenType::Identifier {
127                                if !path.is_empty() {
128                                    path.push('.')
129                                }
130                                path.push_str(self.get_text(leaf.span, source).trim())
131                            }
132                        }
133                    }
134                }
135                return path;
136            }
137            _ => {
138                for child in node.children() {
139                    match child {
140                        RedTree::Leaf(leaf) => {
141                            if leaf.kind == JavaTokenType::Identifier {
142                                return self.get_text(leaf.span, source).trim().to_string();
143                            }
144                        }
145                        RedTree::Node(sub_node) => {
146                            let name = self.extract_identifier(sub_node, source);
147                            if !name.is_empty() {
148                                return name;
149                            }
150                        }
151                    }
152                }
153            }
154        }
155        String::new()
156    }
157
158    fn extract_modifiers(&self, node: RedNode<JavaLanguage>, source: &str) -> Vec<String> {
159        let mut modifiers = Vec::new();
160        for child in node.children() {
161            if let RedTree::Leaf(leaf) = child {
162                match leaf.kind {
163                    JavaTokenType::Public
164                    | JavaTokenType::Private
165                    | JavaTokenType::Protected
166                    | JavaTokenType::Static
167                    | JavaTokenType::Final
168                    | JavaTokenType::Abstract
169                    | JavaTokenType::Native
170                    | JavaTokenType::Synchronized
171                    | JavaTokenType::Transient
172                    | JavaTokenType::Volatile => modifiers.push(self.get_text(leaf.span, source).trim().to_string()),
173                    _ => {}
174                }
175            }
176        }
177        modifiers
178    }
179
180    fn build_class(&self, node: RedNode<JavaLanguage>, source: &str) -> ClassDeclaration {
181        let name = self.extract_identifier(node.clone(), source);
182        let mut members = Vec::new();
183        let modifiers = self.extract_modifiers(node.clone(), source);
184        let mut extends = None;
185        let mut implements = Vec::new();
186
187        for child in node.children() {
188            if let RedTree::Node(sub_node) = child {
189                match sub_node.green.kind {
190                    JavaElementType::MethodDeclaration => members.push(Member::Method(self.build_method(sub_node, source))),
191                    JavaElementType::FieldDeclaration => members.push(Member::Field(self.build_field(sub_node, source))),
192                    JavaElementType::Identifier if extends.is_none() && self.get_text(sub_node.span(), source).trim() != name => {
193                        // This is a bit weak, but if we have an identifier that's not the class name
194                        // and we haven't found extends yet, it might be the superclass.
195                        // Actually, the parser puts Extends/Implements in the GreenNode.
196                    }
197                    _ => self.collect_members(sub_node, source, &mut members),
198                }
199            }
200            else if let RedTree::Leaf(leaf) = child {
201                match leaf.kind {
202                    JavaTokenType::Extends => {
203                        // Next identifier should be the superclass
204                    }
205                    _ => {}
206                }
207            }
208        }
209
210        // Better way to find extends/implements:
211        let mut found_extends = false;
212        let mut found_implements = false;
213        for child in node.children() {
214            match child {
215                RedTree::Leaf(leaf) => {
216                    if leaf.kind == JavaTokenType::Extends {
217                        found_extends = true;
218                        found_implements = false
219                    }
220                    else if leaf.kind == JavaTokenType::Implements {
221                        found_extends = false;
222                        found_implements = true
223                    }
224                }
225                RedTree::Node(sub_node) => {
226                    if sub_node.green.kind == JavaElementType::Identifier {
227                        let id = self.get_text(sub_node.span(), source).trim().to_string();
228                        if id != name && !modifiers.contains(&id) {
229                            if found_extends {
230                                extends = Some(id);
231                                found_extends = false
232                            }
233                            else if found_implements {
234                                implements.push(id)
235                            }
236                        }
237                    }
238                }
239            }
240        }
241
242        ClassDeclaration { modifiers, name, extends, implements, members, span: node.span() }
243    }
244
245    fn build_interface(&self, node: RedNode<JavaLanguage>, source: &str) -> InterfaceDeclaration {
246        let name = self.extract_identifier(node.clone(), source);
247        let mut members = Vec::new();
248        let modifiers = self.extract_modifiers(node.clone(), source);
249        let mut extends = Vec::new();
250
251        let mut found_extends = false;
252        for child in node.children() {
253            match child {
254                RedTree::Leaf(leaf) => {
255                    if leaf.kind == JavaTokenType::Extends {
256                        found_extends = true
257                    }
258                }
259                RedTree::Node(sub_node) => {
260                    if sub_node.green.kind == JavaElementType::Identifier {
261                        let id = self.get_text(sub_node.span(), source).trim().to_string();
262                        if id != name && !modifiers.contains(&id) {
263                            if found_extends {
264                                extends.push(id)
265                            }
266                        }
267                    }
268                    else if sub_node.green.kind == JavaElementType::MethodDeclaration {
269                        members.push(Member::Method(self.build_method(sub_node, source)))
270                    }
271                    else if sub_node.green.kind == JavaElementType::FieldDeclaration {
272                        members.push(Member::Field(self.build_field(sub_node, source)))
273                    }
274                    else {
275                        self.collect_members(sub_node, source, &mut members)
276                    }
277                }
278            }
279        }
280
281        InterfaceDeclaration { modifiers, name, extends, members, span: node.span() }
282    }
283
284    fn build_enum(&self, node: RedNode<JavaLanguage>, source: &str) -> EnumDeclaration {
285        let name = self.extract_identifier(node.clone(), source);
286        let mut members = Vec::new();
287        let modifiers = self.extract_modifiers(node.clone(), source);
288
289        let mut variants = Vec::new();
290
291        for child in node.children() {
292            if let RedTree::Node(sub_node) = child {
293                match sub_node.green.kind {
294                    JavaElementType::Identifier => variants.push(self.get_text(sub_node.span(), source).trim().to_string()),
295                    JavaElementType::MethodDeclaration => members.push(Member::Method(self.build_method(sub_node, source))),
296                    JavaElementType::FieldDeclaration => members.push(Member::Field(self.build_field(sub_node, source))),
297                    _ => self.collect_members(sub_node, source, &mut members),
298                }
299            }
300        }
301
302        EnumDeclaration { modifiers, name, variants, members, span: node.span() }
303    }
304
305    fn build_struct(&self, node: RedNode<JavaLanguage>, source: &str) -> StructDeclaration {
306        StructDeclaration { name: self.extract_identifier(node.clone(), source), modifiers: self.extract_modifiers(node.clone(), source), implements: Vec::new(), members: Vec::new(), span: node.span() }
307    }
308
309    fn build_record(&self, node: RedNode<JavaLanguage>, source: &str) -> RecordDeclaration {
310        RecordDeclaration { name: self.extract_identifier(node.clone(), source), modifiers: self.extract_modifiers(node.clone(), source), parameters: Vec::new(), implements: Vec::new(), members: Vec::new(), span: node.span() }
311    }
312
313    fn collect_members(&self, node: RedNode<JavaLanguage>, source: &str, members: &mut Vec<Member>) {
314        for child in node.children() {
315            if let RedTree::Node(sub_node) = child {
316                match sub_node.green.kind {
317                    JavaElementType::MethodDeclaration => {
318                        // Check if it's a constructor (name matches class name and no return type)
319                        // Actually, let's look at the CST structure.
320                        let method = self.build_method(sub_node.clone(), source);
321                        // If it looks like a constructor, we should have a special check.
322                        // But wait, our build_method might already be confused.
323                        // In Java, constructors don't have return types.
324
325                        // Let's check if the CST node is actually a constructor if we had that kind.
326                        // If not, we check if return_type is empty or matches name?
327                        // Actually, let's just use the MethodDeclaration for now but convert to Constructor if needed.
328
329                        // Wait, I added ConstructorDeclaration to Member.
330                        // Let's see if we can distinguish them.
331                        let is_constructor = self.is_constructor(sub_node.clone(), source);
332                        if is_constructor { members.push(Member::Constructor(self.build_constructor(sub_node, source))) } else { members.push(Member::Method(method)) }
333                    }
334                    JavaElementType::FieldDeclaration => members.push(Member::Field(self.build_field(sub_node, source))),
335                    _ => self.collect_members(sub_node, source, members),
336                }
337            }
338        }
339    }
340
341    fn is_constructor(&self, node: RedNode<JavaLanguage>, _source: &str) -> bool {
342        // A constructor has no return type in the CST.
343        // In our build_method, if return_type is "void" (default) but there was no void keyword,
344        // it might be a constructor.
345
346        // Let's check if there is any type before the name.
347        let mut has_type = false;
348        let mut name_found = false;
349        for child in node.children() {
350            match child {
351                RedTree::Leaf(leaf) => match leaf.kind {
352                    JavaTokenType::Identifier | JavaTokenType::Int | JavaTokenType::Boolean | JavaTokenType::Void | JavaTokenType::Long | JavaTokenType::Float | JavaTokenType::Double | JavaTokenType::Char | JavaTokenType::Byte | JavaTokenType::Short => {
353                        if !name_found {
354                            if has_type { name_found = true } else { has_type = true }
355                        }
356                    }
357                    _ => {}
358                },
359                RedTree::Node(sub_node) => {
360                    if sub_node.green.kind == JavaElementType::Identifier {
361                        if !name_found {
362                            if has_type { name_found = true } else { has_type = true }
363                        }
364                    }
365                }
366            }
367        }
368        !name_found && has_type
369    }
370
371    fn build_constructor(&self, node: RedNode<JavaLanguage>, source: &str) -> ConstructorDeclaration {
372        let mut name = String::new();
373        let mut parameters = Vec::new();
374        let mut body = Vec::new();
375        let modifiers = self.extract_modifiers(node.clone(), source);
376
377        for child in node.children() {
378            match child {
379                RedTree::Leaf(leaf) => match leaf.kind {
380                    JavaTokenType::Identifier => {
381                        if name.is_empty() && !modifiers.contains(&self.get_text(leaf.span, source).trim().to_string()) {
382                            name = self.get_text(leaf.span, source).trim().to_string()
383                        }
384                    }
385                    _ => {}
386                },
387                RedTree::Node(sub_node) => match sub_node.green.kind {
388                    JavaElementType::Identifier => {
389                        if name.is_empty() {
390                            name = self.extract_identifier(sub_node, source)
391                        }
392                    }
393                    JavaElementType::Parameter => parameters.push(self.build_parameter(sub_node, source)),
394                    JavaElementType::BlockStatement => body = self.build_block(sub_node, source),
395                    _ => {}
396                },
397            }
398        }
399
400        ConstructorDeclaration { modifiers, name, parameters, body, span: node.span() }
401    }
402
403    fn build_method(&self, node: RedNode<JavaLanguage>, source: &str) -> MethodDeclaration {
404        let mut name = String::new();
405        let mut return_type = String::new();
406        let mut parameters = Vec::new();
407        let mut body = Vec::new();
408        let mut throws = Vec::new();
409        let mut is_static = false;
410        let modifiers = self.extract_modifiers(node.clone(), source);
411        if modifiers.contains(&"static".to_string()) {
412            is_static = true
413        }
414
415        for child in node.children() {
416            match child {
417                RedTree::Leaf(leaf) => match leaf.kind {
418                    JavaTokenType::Identifier => {
419                        if !modifiers.contains(&self.get_text(leaf.span, source).trim().to_string()) {
420                            if return_type.is_empty() { return_type = self.get_text(leaf.span, source).trim().to_string() } else { name = self.get_text(leaf.span, source).trim().to_string() }
421                        }
422                    }
423                    JavaTokenType::Static => is_static = true,
424                    JavaTokenType::Void | JavaTokenType::Int | JavaTokenType::Boolean => return_type = self.get_text(leaf.span, source).trim().to_string(),
425                    _ => {}
426                },
427                RedTree::Node(sub_node) => match sub_node.green.kind {
428                    JavaElementType::Identifier => {
429                        if return_type.is_empty() {
430                            return_type = self.extract_identifier(sub_node, source)
431                        }
432                        else if name.is_empty() {
433                            name = self.extract_identifier(sub_node, source)
434                        }
435                        else {
436                            throws.push(self.extract_identifier(sub_node, source))
437                        }
438                    }
439                    JavaElementType::Parameter => parameters.push(self.build_parameter(sub_node, source)),
440                    JavaElementType::BlockStatement => body = self.build_block(sub_node, source),
441                    _ => {}
442                },
443            }
444        }
445
446        if return_type.is_empty() {
447            return_type = "void".to_string()
448        }
449
450        MethodDeclaration { modifiers, name, return_type, parameters, body, throws, is_static, span: node.span() }
451    }
452
453    fn build_parameter(&self, node: RedNode<JavaLanguage>, source: &str) -> Parameter {
454        let mut name = String::new();
455        let mut r#type = String::new();
456        let mut is_array = false;
457
458        for child in node.children() {
459            match child {
460                RedTree::Leaf(leaf) => match leaf.kind {
461                    JavaTokenType::Identifier => {
462                        if r#type.is_empty() {
463                            r#type = self.get_text(leaf.span, source).to_string()
464                        }
465                        else {
466                            name = self.get_text(leaf.span, source).to_string()
467                        }
468                    }
469                    JavaTokenType::Int | JavaTokenType::Boolean | JavaTokenType::Void | JavaTokenType::Long | JavaTokenType::Float | JavaTokenType::Double | JavaTokenType::Char | JavaTokenType::Byte | JavaTokenType::Short => {
470                        r#type = self.get_text(leaf.span, source).to_string()
471                    }
472                    JavaTokenType::LeftBracket => is_array = true,
473                    _ => {}
474                },
475                RedTree::Node(sub_node) => {
476                    if sub_node.green.kind == JavaElementType::Identifier {
477                        if r#type.is_empty() { r#type = self.extract_identifier(sub_node, source) } else { name = self.extract_identifier(sub_node, source) }
478                    }
479                }
480            }
481        }
482
483        if is_array {
484            r#type.push_str("[]")
485        }
486
487        Parameter { name, r#type }
488    }
489
490    fn build_field(&self, node: RedNode<JavaLanguage>, source: &str) -> FieldDeclaration {
491        let mut name = String::new();
492        let mut r#type = String::new();
493        let modifiers = self.extract_modifiers(node.clone(), source);
494
495        for child in node.children() {
496            match child {
497                RedTree::Leaf(leaf) => match leaf.kind {
498                    JavaTokenType::Identifier => {
499                        if !modifiers.contains(&self.get_text(leaf.span, source).trim().to_string()) {
500                            if r#type.is_empty() { r#type = self.get_text(leaf.span, source).to_string() } else { name = self.get_text(leaf.span, source).to_string() }
501                        }
502                    }
503                    JavaTokenType::Int | JavaTokenType::Boolean | JavaTokenType::Void | JavaTokenType::Long | JavaTokenType::Float | JavaTokenType::Double | JavaTokenType::Char | JavaTokenType::Byte | JavaTokenType::Short => {
504                        r#type = self.get_text(leaf.span, source).to_string()
505                    }
506                    _ => {}
507                },
508                RedTree::Node(sub_node) => {
509                    if sub_node.green.kind == JavaElementType::Identifier {
510                        if r#type.is_empty() { r#type = self.extract_identifier(sub_node, source) } else { name = self.extract_identifier(sub_node, source) }
511                    }
512                }
513            }
514        }
515
516        FieldDeclaration { modifiers, name, r#type, span: node.span() }
517    }
518
519    fn build_block(&self, node: RedNode<JavaLanguage>, source: &str) -> Vec<Statement> {
520        let mut statements = Vec::new();
521        for child in node.children() {
522            if let RedTree::Node(sub_node) = child {
523                statements.push(self.build_statement(sub_node, source))
524            }
525        }
526        statements
527    }
528
529    fn build_catch_clause(&self, node: RedNode<JavaLanguage>, source: &str) -> CatchClause {
530        let mut parameter = Parameter { name: "".to_string(), r#type: "".to_string() };
531        let mut block = Vec::new();
532        for child in node.children() {
533            if let RedTree::Node(sub_node) = child {
534                match sub_node.green.kind {
535                    JavaElementType::Parameter => parameter = self.build_parameter(sub_node, source),
536                    JavaElementType::BlockStatement => block = self.build_block(sub_node, source),
537                    _ => {}
538                }
539            }
540        }
541        CatchClause { parameter, block }
542    }
543
544    fn build_switch_case(&self, node: RedNode<JavaLanguage>, source: &str) -> SwitchCase {
545        let mut label = None;
546        let mut body = Vec::new();
547        for child in node.children() {
548            if let RedTree::Node(sub_node) = child {
549                if label.is_none() && sub_node.green.kind != JavaElementType::BlockStatement {
550                    label = Some(self.build_expression(sub_node, source))
551                }
552                else if sub_node.green.kind == JavaElementType::BlockStatement {
553                    body.extend(self.build_block(sub_node, source))
554                }
555                else {
556                    body.push(self.build_statement(sub_node, source))
557                }
558            }
559        }
560        SwitchCase { label: label.unwrap_or(Expression::Literal(Literal::Integer(0))), body }
561    }
562
563    fn build_statement(&self, node: RedNode<JavaLanguage>, source: &str) -> Statement {
564        match node.green.kind {
565            JavaElementType::ExpressionStatement => {
566                let mut expr_node = None;
567                for child in node.children() {
568                    if let RedTree::Node(sub_node) = child {
569                        expr_node = Some(sub_node);
570                        break;
571                    }
572                }
573                if let Some(sub_node) = expr_node {
574                    let expr = self.build_expression(sub_node.clone(), source);
575                    return Statement::Expression(expr);
576                }
577                Statement::Block(vec![])
578            }
579            JavaElementType::BlockStatement => Statement::Block(self.build_block(node, source)),
580            JavaElementType::ReturnStatement => {
581                let mut expr = None;
582                for child in node.children() {
583                    if let RedTree::Node(sub_node) = child {
584                        expr = Some(self.build_expression(sub_node, source));
585                        break;
586                    }
587                }
588                Statement::Return(expr)
589            }
590            JavaElementType::IfStatement => {
591                let mut condition = None;
592                let mut then_branch = None;
593                let mut else_branch = None;
594                for child in node.children() {
595                    if let RedTree::Node(sub_node) = child {
596                        if condition.is_none() {
597                            condition = Some(self.build_expression(sub_node, source))
598                        }
599                        else if then_branch.is_none() {
600                            then_branch = Some(Box::new(self.build_statement(sub_node, source)))
601                        }
602                        else {
603                            else_branch = Some(Box::new(self.build_statement(sub_node, source)))
604                        }
605                    }
606                }
607                Statement::If { condition: condition.unwrap_or(Expression::Literal(Literal::Boolean(true))), then_branch: then_branch.unwrap_or(Box::new(Statement::Block(vec![]))), else_branch }
608            }
609            JavaElementType::WhileStatement => {
610                let mut condition = None;
611                let mut body = None;
612                for child in node.children() {
613                    if let RedTree::Node(sub_node) = child {
614                        if condition.is_none() { condition = Some(self.build_expression(sub_node, source)) } else { body = Some(Box::new(self.build_statement(sub_node, source))) }
615                    }
616                }
617                Statement::While { condition: condition.unwrap_or(Expression::Literal(Literal::Boolean(true))), body: body.unwrap_or(Box::new(Statement::Block(vec![]))) }
618            }
619            JavaElementType::DoWhileStatement => {
620                let mut condition = None;
621                let mut body = None;
622                for child in node.children() {
623                    if let RedTree::Node(sub_node) = child {
624                        if body.is_none() { body = Some(Box::new(self.build_statement(sub_node, source))) } else { condition = Some(self.build_expression(sub_node, source)) }
625                    }
626                }
627                Statement::DoWhile { condition: condition.unwrap_or(Expression::Literal(Literal::Boolean(true))), body: body.unwrap_or(Box::new(Statement::Block(vec![]))) }
628            }
629            JavaElementType::ForStatement => {
630                let mut init = None;
631                let mut condition = None;
632                let mut update = None;
633                let mut body = None;
634                let mut semicolon_count = 0;
635                let mut after_right_paren = false;
636
637                for child in node.children() {
638                    match child {
639                        RedTree::Leaf(leaf) => {
640                            if leaf.kind == JavaTokenType::Semicolon {
641                                semicolon_count += 1
642                            }
643                            else if leaf.kind == JavaTokenType::RightParen {
644                                after_right_paren = true
645                            }
646                        }
647                        RedTree::Node(sub_node) => {
648                            if after_right_paren {
649                                if body.is_none() {
650                                    body = Some(Box::new(self.build_statement(sub_node, source)))
651                                }
652                            }
653                            else {
654                                match semicolon_count {
655                                    0 => init = Some(Box::new(self.build_statement(sub_node, source))),
656                                    1 => condition = Some(self.build_expression(sub_node, source)),
657                                    2 => update = Some(self.build_expression(sub_node, source)),
658                                    _ => {}
659                                }
660                            }
661                        }
662                    }
663                }
664                Statement::For { init, condition, update, body: body.unwrap_or(Box::new(Statement::Block(vec![]))) }
665            }
666            JavaElementType::SwitchStatement => {
667                let mut selector = None;
668                let mut cases = Vec::new();
669                let mut default = None;
670                for child in node.children() {
671                    if let RedTree::Node(sub_node) = child {
672                        match sub_node.green.kind {
673                            JavaElementType::SwitchCase => cases.push(self.build_switch_case(sub_node, source)),
674                            JavaElementType::DefaultCase => default = Some(self.build_block(sub_node, source)),
675                            _ => {
676                                if selector.is_none() {
677                                    selector = Some(self.build_expression(sub_node, source))
678                                }
679                            }
680                        }
681                    }
682                }
683                Statement::Switch { selector: selector.unwrap_or(Expression::Identifier("unknown_selector".to_string())), cases, default }
684            }
685            JavaElementType::Break => Statement::Break,
686            JavaElementType::Continue => Statement::Continue,
687            JavaElementType::TryStatement => {
688                let mut block = Vec::new();
689                let mut catches = Vec::new();
690                let mut finally = None;
691                for child in node.children() {
692                    if let RedTree::Node(sub_node) = child {
693                        match sub_node.green.kind {
694                            JavaElementType::BlockStatement => {
695                                if block.is_empty() {
696                                    block = self.build_block(sub_node, source);
697                                }
698                                else {
699                                    finally = Some(self.build_block(sub_node, source));
700                                }
701                            }
702                            JavaElementType::CatchClause => catches.push(self.build_catch_clause(sub_node, source)),
703                            _ => {}
704                        }
705                    }
706                }
707                Statement::Try(TryStatement { block, catches, finally })
708            }
709            JavaElementType::ThrowStatement => {
710                for child in node.children() {
711                    if let RedTree::Node(sub_node) = child {
712                        return Statement::Throw(self.build_expression(sub_node, source));
713                    }
714                }
715                Statement::Throw(Expression::Identifier("unknown_throw".to_string()))
716            }
717            JavaElementType::VariableDeclaration => {
718                let mut r#type = String::new();
719                let mut name = String::new();
720                let mut initializer = None;
721
722                for child in node.children() {
723                    match child {
724                        RedTree::Leaf(leaf) => match leaf.kind {
725                            JavaTokenType::Identifier => {
726                                if r#type.is_empty() {
727                                    r#type = self.get_text(leaf.span, source).to_string()
728                                }
729                                else if name.is_empty() {
730                                    name = self.get_text(leaf.span, source).to_string()
731                                }
732                            }
733                            JavaTokenType::Int | JavaTokenType::Boolean | JavaTokenType::Void | JavaTokenType::Long | JavaTokenType::Float | JavaTokenType::Double | JavaTokenType::Char | JavaTokenType::Byte | JavaTokenType::Short => {
734                                if r#type.is_empty() {
735                                    r#type = self.get_text(leaf.span, source).to_string()
736                                }
737                            }
738                            JavaTokenType::LeftBracket => {
739                                if !r#type.is_empty() {
740                                    r#type.push_str("[]")
741                                }
742                            }
743                            _ => {}
744                        },
745                        RedTree::Node(sub_node) => {
746                            if sub_node.green.kind == JavaElementType::Identifier {
747                                if r#type.is_empty() {
748                                    r#type = self.extract_identifier(sub_node, source)
749                                }
750                                else if name.is_empty() {
751                                    name = self.extract_identifier(sub_node, source)
752                                }
753                                else {
754                                    initializer = Some(self.build_expression(sub_node, source))
755                                }
756                            }
757                            else {
758                                initializer = Some(self.build_expression(sub_node, source))
759                            }
760                        }
761                    }
762                }
763                Statement::LocalVariable { r#type, name, initializer }
764            }
765            _ => Statement::Block(vec![]),
766        }
767    }
768
769    fn build_expression(&self, node: RedNode<JavaLanguage>, source: &str) -> Expression {
770        match node.green.kind {
771            JavaElementType::AssignmentExpression => {
772                let mut left = None;
773                let mut right = None;
774                let mut op = String::new();
775                for child in node.children() {
776                    match child {
777                        RedTree::Node(sub_node) => {
778                            if left.is_none() {
779                                left = Some(Box::new(self.build_expression(sub_node, source)))
780                            }
781                            else {
782                                right = Some(Box::new(self.build_expression(sub_node, source)))
783                            }
784                        }
785                        RedTree::Leaf(leaf) => {
786                            if leaf.kind.role() == oak_core::UniversalTokenRole::Operator || leaf.kind == JavaTokenType::Instanceof {
787                                op = self.get_text(leaf.span, source).trim().to_string()
788                            }
789                        }
790                    }
791                }
792                if let (Some(left), Some(right)) = (left, right) { Expression::Assignment { left, op, right } } else { Expression::Identifier("unknown_assignment".to_string()) }
793            }
794            JavaElementType::UnaryExpression => {
795                let mut expr = None;
796                let mut op = String::new();
797                for child in node.children() {
798                    match child {
799                        RedTree::Node(sub_node) => expr = Some(Box::new(self.build_expression(sub_node, source))),
800                        RedTree::Leaf(leaf) => {
801                            if leaf.kind.role() == oak_core::UniversalTokenRole::Operator || leaf.kind == JavaTokenType::Instanceof {
802                                op = self.get_text(leaf.span, source).trim().to_string();
803                            }
804                        }
805                    }
806                }
807                if let Some(expression) = expr { if op == "++" || op == "--" { Expression::Update { expression, op, is_prefix: true } } else { Expression::Unary { op, expression } } } else { Expression::Identifier("unknown_unary".to_string()) }
808            }
809            JavaElementType::PostfixExpression => {
810                let mut expr = None;
811                let mut op = String::new();
812                for child in node.children() {
813                    match child {
814                        RedTree::Node(sub_node) => expr = Some(Box::new(self.build_expression(sub_node, source))),
815                        RedTree::Leaf(leaf) => {
816                            if leaf.kind.role() == oak_core::UniversalTokenRole::Operator || leaf.kind == JavaTokenType::Instanceof {
817                                op = self.get_text(leaf.span, source).trim().to_string();
818                            }
819                        }
820                    }
821                }
822                if let Some(expression) = expr { Expression::Update { expression, op, is_prefix: false } } else { Expression::Identifier("unknown_postfix".to_string()) }
823            }
824            JavaElementType::TernaryExpression => {
825                let mut condition = None;
826                let mut then_branch = None;
827                let mut else_branch = None;
828                for child in node.children() {
829                    if let RedTree::Node(sub_node) = child {
830                        if condition.is_none() {
831                            condition = Some(Box::new(self.build_expression(sub_node, source)));
832                        }
833                        else if then_branch.is_none() {
834                            then_branch = Some(Box::new(self.build_expression(sub_node, source)));
835                        }
836                        else {
837                            else_branch = Some(Box::new(self.build_expression(sub_node, source)));
838                        }
839                    }
840                }
841                if let (Some(condition), Some(then_branch), Some(else_branch)) = (condition, then_branch, else_branch) { Expression::Ternary { condition, then_branch, else_branch } } else { Expression::Identifier("unknown_ternary".to_string()) }
842            }
843            JavaElementType::CastExpression => {
844                let mut target_type = String::new();
845                let mut expr = None;
846                for child in node.children() {
847                    match child {
848                        RedTree::Node(sub_node) => {
849                            if target_type.is_empty() {
850                                target_type = self.extract_identifier(sub_node, source);
851                            }
852                            else {
853                                expr = Some(Box::new(self.build_expression(sub_node, source)));
854                            }
855                        }
856                        RedTree::Leaf(leaf) => {
857                            if target_type.is_empty() && (leaf.kind == JavaTokenType::Identifier || leaf.kind.role() == oak_core::UniversalTokenRole::Keyword) {
858                                target_type = self.get_text(leaf.span, source).trim().to_string();
859                            }
860                        }
861                    }
862                }
863                if let Some(expression) = expr { Expression::Cast { target_type, expression } } else { Expression::Identifier("unknown_cast".to_string()) }
864            }
865            JavaElementType::BinaryExpression => {
866                let mut left = None;
867                let mut right = None;
868                let mut op = String::new();
869                for child in node.children() {
870                    match child {
871                        RedTree::Node(sub_node) => {
872                            if left.is_none() {
873                                left = Some(Box::new(self.build_expression(sub_node, source)))
874                            }
875                            else {
876                                right = Some(Box::new(self.build_expression(sub_node, source)))
877                            }
878                        }
879                        RedTree::Leaf(leaf) => {
880                            if leaf.kind.role() == oak_core::UniversalTokenRole::Operator || leaf.kind == JavaTokenType::Instanceof {
881                                op = self.get_text(leaf.span, source).trim().to_string();
882                            }
883                        }
884                    }
885                }
886                if let (Some(left), Some(right)) = (left, right) { Expression::Binary { left, op, right } } else { Expression::Identifier("unknown_binary".to_string()) }
887            }
888            JavaElementType::LiteralExpression => {
889                for child in node.children() {
890                    match child {
891                        RedTree::Leaf(leaf) => match leaf.kind {
892                            JavaTokenType::IntegerLiteral => {
893                                let text = self.get_text(leaf.span, source).trim().to_string();
894                                println!("DEBUG: Parsing IntegerLiteral: '{}'", text);
895                                let val = text.parse().unwrap_or(0);
896                                return Expression::Literal(Literal::Integer(val));
897                            }
898                            JavaTokenType::FloatingPointLiteral => {
899                                let text = self.get_text(leaf.span, source).trim().to_string();
900                                let val = text.parse().unwrap_or(0.0);
901                                return Expression::Literal(Literal::Float(val));
902                            }
903                            JavaTokenType::StringLiteral => {
904                                let text = self.get_text(leaf.span, source).trim();
905                                let content = if text.len() >= 2 { &text[1..text.len() - 1] } else { text };
906                                return Expression::Literal(Literal::String(content.to_string()));
907                            }
908                            JavaTokenType::BooleanLiteral => {
909                                let val = self.get_text(leaf.span, source).trim() == "true";
910                                return Expression::Literal(Literal::Boolean(val));
911                            }
912                            _ => {}
913                        },
914                        RedTree::Node(sub_node) => {
915                            let expr = self.build_expression(sub_node, source);
916                            if let Expression::Literal(_) = expr {
917                                return expr;
918                            }
919                        }
920                    }
921                }
922                // Fallback: try to parse the whole node text as a literal if it's a leaf-like node
923                let text = self.get_text(node.span(), source).trim().to_string();
924                if let Ok(val) = text.parse::<i64>() {
925                    return Expression::Literal(Literal::Integer(val));
926                }
927                if let Ok(val) = text.parse::<f64>() {
928                    return Expression::Literal(Literal::Float(val));
929                }
930                Expression::Identifier("unknown".to_string())
931            }
932            JavaElementType::MethodCall => {
933                let mut callee = None;
934                let mut arguments = Vec::new();
935
936                for child in node.children() {
937                    match child {
938                        RedTree::Node(sub_node) => {
939                            if callee.is_none() {
940                                callee = Some(self.build_expression(sub_node, source));
941                            }
942                            else {
943                                arguments.push(self.build_expression(sub_node, source));
944                            }
945                        }
946                        _ => {}
947                    }
948                }
949
950                if let Some(expr) = callee {
951                    match expr {
952                        Expression::FieldAccess(fa) => Expression::MethodCall(MethodCall { target: Some(fa.target), name: fa.name, arguments }),
953                        Expression::Identifier(name) => Expression::MethodCall(MethodCall { target: None, name, arguments }),
954                        _ => Expression::MethodCall(MethodCall { target: Some(Box::new(expr)), name: "unknown".to_string(), arguments }),
955                    }
956                }
957                else {
958                    Expression::Identifier("unknown".to_string())
959                }
960            }
961            JavaElementType::MemberSelect => {
962                let mut target = None;
963                let mut name = String::new();
964                for child in node.children() {
965                    match child {
966                        RedTree::Node(sub_node) => target = Some(Box::new(self.build_expression(sub_node, source))),
967                        RedTree::Leaf(leaf) => {
968                            if leaf.kind == JavaTokenType::Identifier {
969                                name = self.get_text(leaf.span, source).trim().to_string();
970                            }
971                        }
972                    }
973                }
974                if let Some(target) = target { Expression::FieldAccess(FieldAccess { target, name }) } else { Expression::Identifier(name) }
975            }
976            JavaElementType::ArrayAccess => {
977                let mut target = None;
978                let mut index = None;
979                for child in node.children() {
980                    if let RedTree::Node(sub_node) = child {
981                        if target.is_none() {
982                            target = Some(Box::new(self.build_expression(sub_node, source)));
983                        }
984                        else {
985                            index = Some(Box::new(self.build_expression(sub_node, source)));
986                        }
987                    }
988                }
989                if let (Some(target), Some(index)) = (target, index) { Expression::ArrayAccess(ArrayAccess { target, index }) } else { Expression::Identifier("unknown_array_access".to_string()) }
990            }
991            JavaElementType::ArrayCreation => {
992                let mut element_type = String::new();
993                let mut dimensions = Vec::new();
994                for child in node.children() {
995                    match child {
996                        RedTree::Leaf(leaf) => {
997                            if leaf.kind == JavaTokenType::Identifier || leaf.kind.role() == oak_core::UniversalTokenRole::Keyword {
998                                if element_type.is_empty() {
999                                    element_type = self.get_text(leaf.span, source).to_string()
1000                                }
1001                            }
1002                        }
1003                        RedTree::Node(sub_node) => dimensions.push(self.build_expression(sub_node, source)),
1004                    }
1005                }
1006                Expression::ArrayCreation(ArrayCreation { element_type, dimensions })
1007            }
1008            JavaElementType::Identifier => {
1009                let name = self.get_text(node.span(), source).trim().to_string();
1010                match name.as_str() {
1011                    "this" => Expression::This,
1012                    "super" => Expression::Super,
1013                    _ => Expression::Identifier(name),
1014                }
1015            }
1016            JavaElementType::NewExpression => {
1017                let mut r#type = String::new();
1018                let mut arguments = Vec::new();
1019                for child in node.children() {
1020                    match child {
1021                        RedTree::Leaf(leaf) => {
1022                            if leaf.kind == JavaTokenType::Identifier && r#type.is_empty() {
1023                                r#type = self.get_text(leaf.span, source).to_string()
1024                            }
1025                        }
1026                        RedTree::Node(sub_node) => {
1027                            if r#type.is_empty() {
1028                                r#type = self.extract_identifier(sub_node, source)
1029                            }
1030                            else {
1031                                arguments.push(self.build_expression(sub_node, source));
1032                            }
1033                        }
1034                    }
1035                }
1036                Expression::New(NewExpression { r#type, arguments })
1037            }
1038            JavaElementType::ParenthesizedExpression => {
1039                for child in node.children() {
1040                    if let RedTree::Node(sub_node) = child {
1041                        return self.build_expression(sub_node, source);
1042                    }
1043                }
1044                Expression::Identifier("unknown_parenthesized".to_string())
1045            }
1046            _ => {
1047                for child in node.children() {
1048                    if let RedTree::Leaf(leaf) = child {
1049                        if leaf.kind == JavaTokenType::Identifier {
1050                            let name = self.get_text(leaf.span, source).trim().to_string();
1051                            return Expression::Identifier(name);
1052                        }
1053                    }
1054                    else if let RedTree::Node(sub_node) = child {
1055                        return self.build_expression(sub_node, source);
1056                    }
1057                }
1058                Expression::Identifier("unknown".to_string())
1059            }
1060        }
1061    }
1062}
1063
1064impl<'config> Builder<JavaLanguage> for JavaBuilder<'config> {
1065    fn build<'a, S: Source + ?Sized>(&self, text: &S, edits: &[TextEdit], cache: &'a mut impl BuilderCache<JavaLanguage>) -> BuildOutput<JavaLanguage> {
1066        let parser = JavaParser::new(self.language);
1067        let output = parser.parse(text, edits, cache);
1068        let result = output.result.map(|green| self.build_root(green, &text.get_text_in((0..text.length()).into())));
1069        oak_core::errors::OakDiagnostics { result, diagnostics: output.diagnostics }
1070    }
1071}