2024-06-10 09:47:48 +02:00
|
|
|
use std::{
|
|
|
|
clone, fs,
|
|
|
|
path::{Path, PathBuf},
|
|
|
|
sync::{Arc, Mutex, RwLock},
|
|
|
|
};
|
|
|
|
|
|
|
|
use dashmap::DashMap;
|
|
|
|
use rowan::ast::{AstNode, AstPtr};
|
|
|
|
|
2024-06-23 20:32:10 +02:00
|
|
|
use crate::{
|
|
|
|
lst_parser::{
|
|
|
|
error::SyntaxError, grammar::source_file, input::Input, output::Output, syntax_kind, Parser,
|
|
|
|
},
|
|
|
|
Lang,
|
2024-06-10 09:47:48 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
use super::{error::Error, modules::Module, nodes};
|
|
|
|
|
2024-06-23 20:32:10 +02:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct Loc<N: AstNode<Language = Lang>> {
|
2024-06-10 09:47:48 +02:00
|
|
|
file: FileId,
|
|
|
|
syntax: AstPtr<N>,
|
|
|
|
}
|
|
|
|
|
2024-06-23 20:32:10 +02:00
|
|
|
impl<N: AstNode<Language = Lang>> Loc<N> {
|
|
|
|
pub fn new(node: N, file: FileId) -> Self {
|
|
|
|
Self {
|
|
|
|
file,
|
|
|
|
syntax: AstPtr::new(&node),
|
|
|
|
}
|
2024-06-10 09:47:48 +02:00
|
|
|
}
|
|
|
|
|
2024-06-23 20:32:10 +02:00
|
|
|
pub fn file(&self) -> FileId {
|
|
|
|
self.file
|
2024-06-10 09:47:48 +02:00
|
|
|
}
|
|
|
|
|
2024-06-23 20:32:10 +02:00
|
|
|
pub fn syntax(&self) -> AstPtr<N> {
|
|
|
|
self.syntax.clone()
|
2024-06-10 09:47:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// global file store
|
|
|
|
/// contains all known files etc.
|
2024-06-23 20:32:10 +02:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct Files {
|
|
|
|
paths: Arc<Mutex<Vec<PathBuf>>>,
|
|
|
|
store: Arc<DashMap<PathBuf, Arc<SourceFile>>>,
|
2024-06-10 09:47:48 +02:00
|
|
|
}
|
|
|
|
|
2024-06-23 20:32:10 +02:00
|
|
|
impl Files {
|
|
|
|
pub fn new() -> Self {
|
2024-06-10 09:47:48 +02:00
|
|
|
Self {
|
2024-06-23 20:32:10 +02:00
|
|
|
paths: Arc::new(Mutex::new(Vec::new())),
|
|
|
|
store: Arc::new(DashMap::new()),
|
2024-06-10 09:47:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-23 20:32:10 +02:00
|
|
|
pub fn add_and_parse(&self, path: &Path) -> Result<(FileId, Vec<Error>), std::io::Error> {
|
2024-06-10 09:47:48 +02:00
|
|
|
let (file, errors) = SourceFile::read_and_parse(&path)?;
|
|
|
|
|
|
|
|
// add file to paths and unlock again
|
|
|
|
let id = {
|
|
|
|
let path = path.clone();
|
|
|
|
let mut paths = self.paths.lock().unwrap();
|
|
|
|
let r = paths.len();
|
|
|
|
paths.push(path.to_path_buf());
|
|
|
|
FileId(r)
|
|
|
|
};
|
|
|
|
|
|
|
|
let _ = self.store.insert(path.to_path_buf(), Arc::new(file));
|
|
|
|
|
|
|
|
Ok((
|
|
|
|
id,
|
|
|
|
errors
|
|
|
|
.into_iter()
|
|
|
|
.map(|e| Error::from_syntax(id, e))
|
|
|
|
.collect(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2024-06-23 20:32:10 +02:00
|
|
|
pub fn get(&self, id: FileId) -> Arc<SourceFile> {
|
2024-06-10 09:47:48 +02:00
|
|
|
let path = {
|
|
|
|
let paths = self.paths.lock().unwrap();
|
|
|
|
paths[id.0].clone()
|
|
|
|
};
|
|
|
|
|
|
|
|
self.store.get(&path).unwrap().clone()
|
|
|
|
}
|
2024-06-23 20:32:10 +02:00
|
|
|
|
|
|
|
pub fn get_path(&self, id: FileId) -> PathBuf {
|
|
|
|
let paths = self.paths.lock().unwrap();
|
|
|
|
paths[id.0].clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn path_store(&self) -> Arc<Mutex<Vec<PathBuf>>> {
|
|
|
|
self.paths.clone()
|
|
|
|
}
|
2024-06-10 09:47:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct SourceFile {
|
2024-06-23 20:32:10 +02:00
|
|
|
pub lst: RwLock<rowan::GreenNode>,
|
2024-06-10 09:47:48 +02:00
|
|
|
root_module: Option<Arc<Module>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SourceFile {
|
|
|
|
fn read_and_parse(path: &Path) -> Result<(Self, Vec<SyntaxError>), std::io::Error> {
|
|
|
|
let source_text = fs::read_to_string(&path)?;
|
|
|
|
|
|
|
|
let toks = syntax_kind::lex(&source_text);
|
|
|
|
let input = Input::new(&toks);
|
|
|
|
let mut parser = Parser::new(input);
|
|
|
|
|
|
|
|
source_file(&mut parser);
|
|
|
|
|
|
|
|
let events = parser.finish();
|
|
|
|
let out = Output::from_parser_output(toks, events);
|
2024-06-23 20:32:10 +02:00
|
|
|
// let lst = out.syntax();
|
|
|
|
let (lst, errors) = out.dissolve();
|
2024-06-10 09:47:48 +02:00
|
|
|
|
|
|
|
Ok((
|
|
|
|
Self {
|
2024-06-23 20:32:10 +02:00
|
|
|
lst: RwLock::new(lst),
|
2024-06-10 09:47:48 +02:00
|
|
|
root_module: None,
|
|
|
|
},
|
2024-06-23 20:32:10 +02:00
|
|
|
errors,
|
2024-06-10 09:47:48 +02:00
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
pub struct FileId(pub usize);
|