fix: Undo accidental behaviour change on name to path resolution

This commit is contained in:
Nicolas Abril 2023-05-12 20:33:45 +02:00
parent 73ac68860c
commit d3cac034fe

View File

@ -12,7 +12,6 @@ use std::rc::Rc;
use strsim::jaro; use strsim::jaro;
use kind_pass::unbound::{self, UnboundCollector}; use kind_pass::unbound::{self, UnboundCollector};
use kind_report::data::Diagnostic;
use kind_tree::concrete::visitor::Visitor; use kind_tree::concrete::visitor::Visitor;
use kind_tree::concrete::{Book, Module, TopLevel}; use kind_tree::concrete::{Book, Module, TopLevel};
use kind_tree::symbol::{Ident, QualifiedIdent}; use kind_tree::symbol::{Ident, QualifiedIdent};
@ -116,43 +115,57 @@ pub fn check_unbounds(session: &mut Session, book: &mut Book) -> anyhow::Result<
} }
} }
/// Returns the path to the file that contains a given identifier, /// Returns the path to the file that contains a given
/// or `None` if no available options were found. /// identifier, or `None` if no available options were found.
/// ///
/// In case more than one path is available, /// In case more than one path is available, return
/// return a `Diagnostic` indicating that. /// an `Err` and send a diagnostic to `session`.
fn ident_to_path( fn ident_to_path(
session: &Session,
root: &Path, root: &Path,
ident: &QualifiedIdent, ident: &QualifiedIdent,
) -> Result<Option<PathBuf>, Box<dyn Diagnostic>> { ) -> Result<Option<PathBuf>, ()> {
// Data/Bool/True // Data/Bool
let relative_path = PathBuf::from(ident.to_str().replace('.', "/")); let relative_path = PathBuf::from(ident.to_str().replace('.', "/"));
// root/Data/Bool/True // root/Data/Bool
let base_path = root.join(relative_path); let base_path = root.join(relative_path);
// root/Data/Bool/True.kind2 match search_ident_path(session, &base_path, ident) {
let file = base_path.with_extension(EXT); Ok(None) if SEARCH_IDENT_ON_PARENT => {
// root/Data/Bool/True/_.kind2 // Also accept files on parent scope
let dir = base_path.join(DIR_FILE); search_ident_path(session, base_path.parent().unwrap(), ident)
let search_options = if SEARCH_IDENT_ON_PARENT { }
// root/Data/Bool.kind2 res => res,
let par_file = base_path.parent().unwrap().with_extension(EXT); }
// root/Data/Bool/_.kind2 }
let par_dir = base_path.parent().unwrap().join(DIR_FILE);
vec![file, dir, par_file, par_dir]
} else {
vec![file, dir]
};
// All the found paths that could contain the definition of this Identifier
let available_paths: Vec<_> = search_options.into_iter().filter(|p| p.is_file()).collect();
/// Given a `base_path` resulting from a conversion of an identifier,
/// return the paths that could contain the identifier, relative to `base_path`.
///
/// Returns `None` if there are no matching files available.
///
/// Returns `Err` in case there is more than one file available,
/// sending an error diagnostic to `session'.
fn search_ident_path(
session: &Session,
base_path: &Path,
ident: &QualifiedIdent,
) -> Result<Option<PathBuf>, ()> {
// root/Data/Bool.kind2
// root/Data/Bool/_.kind2
let file = base_path.with_extension(EXT);
let dir = base_path.join(DIR_FILE);
let search_options = vec![file, dir];
let available_paths: Vec<_> = search_options.into_iter().filter(|p| p.is_file()).collect();
match available_paths.len() { match available_paths.len() {
0 => Ok(None), 0 => Ok(None),
1 => Ok(Some(available_paths.into_iter().next().unwrap())), 1 => Ok(Some(available_paths.into_iter().next().unwrap())),
_ => Err(Box::new(DriverDiagnostic::MultiplePaths( _ => {
ident.clone(), let diag = DriverDiagnostic::MultiplePaths(ident.clone(), available_paths);
available_paths, session.diagnostic_sender.send(Box::new(diag)).unwrap();
))), Err(())
}
} }
} }
@ -267,13 +280,10 @@ fn load_file_to_book_by_identifier(
if book.entries.contains_key(ident.to_string().as_str()) { if book.entries.contains_key(ident.to_string().as_str()) {
return false; return false;
} }
match ident_to_path(&session.root, ident) { match ident_to_path(session, &session.root, ident) {
Ok(Some(path)) => load_file_to_book(session, &path, book, false), Ok(Some(path)) => load_file_to_book(session, &path, book, false),
Ok(None) => false, Ok(None) => false,
Err(err) => { Err(()) => true,
session.diagnostic_sender.send(err).unwrap();
true
}
} }
} }