summaryrefslogtreecommitdiff
path: root/src/source_unit.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/source_unit.rs')
-rw-r--r--src/source_unit.rs67
1 files changed, 42 insertions, 25 deletions
diff --git a/src/source_unit.rs b/src/source_unit.rs
index 3e30284..9c51ccb 100644
--- a/src/source_unit.rs
+++ b/src/source_unit.rs
@@ -1,10 +1,10 @@
use crate::*;
-use log::info;
+use log::{info, warn};
use vagabond::*;
-type ParseFn = fn(&str, Option<&Path>) -> Vec<Symbol>;
+type ParseFn = fn(&str, Option<&Path>) -> Option<Vec<Symbol>>;
/// Gather all source units with a given extension using a PATH-style environment variable.
@@ -22,20 +22,39 @@ pub fn gather_from_path_variable(variable: &str, extension: Option<&str>, parse:
/// Gather source units with a given extension at or descending from a path.
pub fn gather_from_path(path: &Path, extension: Option<&str>, parse: ParseFn) -> Vec<SourceUnit> {
let mut source_units = Vec::new();
+ let check_optional_file = |file: &Option<SourceFile>| -> bool {
+ match file {
+ Some(file) => match file.symbols {
+ Some(_) => { info!("Found source file at {:?}", file.path); true }
+ None => { warn!("Could not parse source file at {:?}", file.path); false }
+ }
+ None => true,
+ }
+ };
+ let mut gather_source_unit = |path: &Path| {
+ if let Ok(unit) = SourceUnit::from_path(&path, extension, parse) {
+ if unit.main.symbols.is_some() {
+ info!("Found source file at {:?}", unit.main.path);
+ let head_good = check_optional_file(&unit.head);
+ let tail_good = check_optional_file(&unit.tail);
+ if head_good && tail_good {
+ source_units.push(unit);
+ }
+ } else {
+ warn!("Could not parse source file at {path:?}");
+ check_optional_file(&unit.head);
+ check_optional_file(&unit.tail);
+ }
+ }
+ };
if let Ok(entry) = Entry::from_path(path) {
if EntryType::File == entry.entry_type {
- if let Ok(unit) = SourceUnit::from_path(&entry.path, extension, parse) {
- info!("Found source file at {path:?}");
- source_units.push(unit);
- }
+ gather_source_unit(&entry.path)
} else if EntryType::Directory == entry.entry_type {
info!("Traversing directory {path:?} for source files");
if let Ok(entries) = traverse_directory(entry.path) {
for entry in entries {
- if let Ok(unit) = SourceUnit::from_path(&entry.path, extension, parse) {
- info!("Found source file at {:?}", entry.path);
- source_units.push(unit);
- }
+ gather_source_unit(&entry.path)
}
}
}
@@ -66,29 +85,27 @@ impl SourceUnit {
// Head and tail files will be picked up later along with the main file.
if !is_main || is_head || is_tail { return Err(FileError::InvalidExtension); }
+ let parse_file = |path: PathBuf| {
+ if let Ok(source_code) = read_file(&path) {
+ let symbols = parse(&source_code, Some(&path));
+ return Some(SourceFile { symbols, source_code, path: path });
+ }
+ return None;
+ };
+ let head = head_extension.map_or(None, |ext| parse_file(main_path.with_extension(&ext)));
+ let tail = tail_extension.map_or(None, |ext| parse_file(main_path.with_extension(&ext)));
let source_code = read_file(path.as_ref())?;
let symbols = parse(&source_code, Some(path.as_ref()));
- macro_rules! parse_file {
- ($path:expr) => {
- read_file(&$path).ok().map(|source_code| {
- let symbols = parse(&source_code, Some(&$path));
- let path = $path;
- SourceFile { symbols, source_code, path }
- })
- };
- }
-
- let head = head_extension.map_or(None, |ext| parse_file!(main_path.with_extension(&ext)));
- let tail = tail_extension.map_or(None, |ext| parse_file!(main_path.with_extension(&ext)));
let main = SourceFile { path: main_path, source_code, symbols };
- Ok( SourceUnit { main, head, tail } )
+ Ok(SourceUnit { main, head, tail })
}
/// Load from a string of source code.
pub fn from_string<P: AsRef<Path>>(source_code: String, path: P, parse: ParseFn) -> Self {
let path = { path.as_ref().canonicalize().unwrap_or_else(|_| path.as_ref().to_path_buf()) };
let symbols = parse(&source_code, Some(&path));
- Self { main: SourceFile { path, source_code, symbols }, head: None, tail: None }
+ let main = SourceFile { path, source_code, symbols };
+ Self { main, head: None, tail: None }
}
pub fn name(&self) -> Option<String> {
@@ -105,7 +122,7 @@ impl SourceUnit {
pub struct SourceFile {
pub path: PathBuf,
pub source_code: String,
- pub symbols: Vec<Symbol>,
+ pub symbols: Option<Vec<Symbol>>,
}
pub struct Symbol {