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 }
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 }
205 _ => {}
206 }
207 }
208 }
209
210 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 let method = self.build_method(sub_node.clone(), source);
321 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 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 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}