use std::{ collections::HashMap, io, path::{Path, PathBuf}, }; mod loc; pub use loc::Loc; use rowan::ast::AstNode; use crate::{ ast::ParseError, lst_parser::{self, error::SyntaxError, input, output::Output}, world::{error::Error, files::source_file::SourceFile}, }; struct Files { inner: Vec, path_to_id_map: HashMap, } impl Files { pub fn add_file(&mut self, path: &Path) -> Result<(FileId, Vec), OpenFileError> { if !path.exists() { return Err(OpenFileError::NotFound(path.to_owned())); } let file_id = FileId(self.inner.len()); let (source_file, errs) = match SourceFile::open(path) { Ok((source_file, errs)) => { let errs = errs .into_iter() .map(|(ptr, err)| Error::Syntax(Loc::from_ptr(ptr, file_id), err)) .collect::>(); (source_file, errs) } Err(e) => return Err(OpenFileError::IoError(path.to_path_buf(), e)), }; self.inner.push(source_file); self.path_to_id_map.insert(path.to_path_buf(), file_id); Ok((file_id, errs)) } } pub enum OpenFileError { NotFound(PathBuf), IoError(PathBuf, std::io::Error), } #[derive(Copy, Clone, Debug)] pub struct FileId(usize); mod source_file;