1use crate::{ast::*, language::VLangLanguage, lexer::token_type::VLangTokenType, parser::element_type::VLangElementType};
2use core::range::Range;
3use oak_core::{
4 GreenNode, Parser, Source, TokenType,
5 builder::{BuildOutput, Builder},
6 source::TextEdit,
7 tree::red_tree::{RedNode, RedTree},
8};
9
10pub struct VLangBuilder<'config> {
12 language: &'config VLangLanguage,
13}
14
15impl<'config> VLangBuilder<'config> {
16 pub fn new(language: &'config VLangLanguage) -> Self {
18 Self { language }
19 }
20
21 fn build_root(&self, green: &GreenNode<VLangLanguage>, source: &str) -> VRoot {
22 let red = RedNode::new(green, 0);
23 let mut module_name = String::new();
24 let mut imports = Vec::new();
25 let mut items = Vec::new();
26
27 for child in red.children() {
30 if let RedTree::Node(node) = child {
31 items.push(self.build_item(node, source));
34 }
35 }
36
37 VRoot { module_name, imports, items }
38 }
39
40 fn build_item(&self, node: RedNode<VLangLanguage>, source: &str) -> VItem {
41 VItem::Function(VFunction { name: "unknown".to_string(), is_pub: false, receiver: None, params: Vec::new(), return_type: None, body: Vec::new() })
43 }
44
45 fn get_text<'a>(&self, span: Range<usize>, source: &'a str) -> &'a str {
46 let start = span.start;
47 let end = span.end;
48 if start > source.len() || end > source.len() || start > end {
49 return "";
50 }
51 &source[start..end]
52 }
53}
54
55impl<'config> Builder<VLangLanguage> for VLangBuilder<'config> {
56 fn build<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl oak_core::parser::ParseCache<VLangLanguage>) -> BuildOutput<VLangLanguage> {
57 let parser = crate::parser::VLangParser::new(self.language);
58 let output = parser.parse(text, edits, cache);
59
60 let source_str = text.get_text_in(Range { start: 0, end: text.length() });
61 let result = output.result.map(|green| self.build_root(green, &source_str));
62
63 oak_core::errors::OakDiagnostics { result, diagnostics: output.diagnostics }
64 }
65}