datex_core/compiler/
workspace.rs

1use url::Url;
2
3use crate::collections::HashMap;
4use crate::compiler::error::DetailedCompilerErrors;
5use crate::compiler::error::DetailedCompilerErrorsWithMaybeRichAst;
6use crate::compiler::precompiler::precompiled_ast::RichAst;
7use crate::compiler::{
8    CompileOptions, parse_datex_script_to_rich_ast_detailed_errors,
9};
10use crate::runtime::Runtime;
11use crate::values::core_values::r#type::Type;
12
13/// Represents a file in the compiler workspace with its URL, cached content and AST.
14pub struct WorkspaceFile {
15    pub url: Url,
16    pub content: String,
17    pub rich_ast: Option<RichAst>,
18    pub return_type: Option<Type>,
19    pub errors: Option<DetailedCompilerErrors>,
20}
21
22/// Represents the compiler workspace containing multiple files.
23pub struct CompilerWorkspace {
24    files: HashMap<Url, WorkspaceFile>,
25    runtime: Runtime,
26}
27
28impl CompilerWorkspace {
29    /// Creates a new compiler workspace with the given runtime.
30    pub fn new(runtime: Runtime) -> Self {
31        Self {
32            files: HashMap::new(),
33            runtime,
34        }
35    }
36
37    pub fn files(&self) -> &HashMap<Url, WorkspaceFile> {
38        &self.files
39    }
40
41    /// Loads a file into the workspace, caching its content and AST.
42    /// Returns a compiler error if parsing or precompilation fails.
43    pub fn load_file(&mut self, url: Url, content: String) -> &WorkspaceFile {
44        let result = self.get_rich_ast_for_file(&url, content.clone());
45        let workspace_file = match result {
46            Ok(rich_ast) => WorkspaceFile {
47                url: url.clone(),
48                content,
49                rich_ast: Some(rich_ast),
50                return_type: None,
51                errors: None,
52            },
53            Err(error) => WorkspaceFile {
54                url: url.clone(),
55                content,
56                rich_ast: error.ast,
57                return_type: None,
58                errors: Some(error.errors),
59            },
60        };
61        self.files.insert(url.clone(), workspace_file);
62        self.files.get(&url).unwrap()
63    }
64
65    /// Retrieves a reference to a workspace file by its URL.
66    pub fn get_file(&self, url: &Url) -> Option<&WorkspaceFile> {
67        self.files.get(url)
68    }
69
70    pub fn get_file_mut(&mut self, url: &Url) -> Option<&mut WorkspaceFile> {
71        self.files.get_mut(url)
72    }
73
74    /// Retrieves the AST with metadata for a given file path and content after parsing and compilation.
75    /// Returns a compiler error if parsing or compilation fails.
76    fn get_rich_ast_for_file(
77        &self,
78        url: &Url,
79        content: String,
80    ) -> Result<RichAst, DetailedCompilerErrorsWithMaybeRichAst> {
81        let mut options = CompileOptions::default();
82        let rich_ast = parse_datex_script_to_rich_ast_detailed_errors(
83            &content,
84            &mut options,
85        )?;
86        Ok(rich_ast)
87    }
88}