summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/resolver.rs39
-rw-r--r--src/source_unit.rs67
2 files changed, 65 insertions, 41 deletions
diff --git a/src/resolver.rs b/src/resolver.rs
index 2b49055..8d3a16d 100644
--- a/src/resolver.rs
+++ b/src/resolver.rs
@@ -43,12 +43,20 @@ impl Resolver {
let source_id = self.source_units.len();
use std::mem::take;
- info!("Including source file at {:?}", source_unit.main.path);
- self.include_symbols(take(&mut source_unit.main.symbols), source_id, SourceRole::Main);
+ info!("Including source unit at {:?}", source_unit.main.path);
+ if let Some(symbols) = &mut source_unit.main.symbols {
+ self.include_symbols(take(symbols), source_id, SourceRole::Main);
+ }
if let Some(head) = &mut source_unit.head {
- self.include_symbols(take(&mut head.symbols), source_id, SourceRole::Head); }
+ if let Some(symbols) = &mut head.symbols {
+ self.include_symbols(take(symbols), source_id, SourceRole::Head);
+ }
+ }
if let Some(tail) = &mut source_unit.tail {
- self.include_symbols(take(&mut tail.symbols), source_id, SourceRole::Tail); }
+ if let Some(symbols) = &mut tail.symbols {
+ self.include_symbols(take(symbols), source_id, SourceRole::Tail);
+ }
+ }
match parent_id {
Some(parent_id) => match self.source_units.get_mut(parent_id) {
@@ -153,19 +161,18 @@ impl Resolver {
/// Return the ID of a source unit that contains an unresolved reference
/// to a symbol defined by this unit.
fn unit_resolved_by_unit(&self, source_unit: &SourceUnit) -> Option<usize> {
- if let Some(id) = self.unit_resolved_by_symbol(&source_unit.main.symbols) {
- return Some(id);
- }
- if let Some(head) = &source_unit.head {
- if let Some(id) = self.unit_resolved_by_symbol(&head.symbols) {
- return Some(id);
- }
- }
- if let Some(tail) = &source_unit.tail {
- if let Some(id) = self.unit_resolved_by_symbol(&tail.symbols) {
- return Some(id);
- }
+ macro_rules! return_resolved_unit {
+ ($file:expr) => {
+ if let Some(symbols) = &$file.symbols {
+ if let Some(id) = self.unit_resolved_by_symbol(&symbols) {
+ return Some(id);
+ }
+ }
+ };
}
+ return_resolved_unit!(&source_unit.main);
+ if let Some(head) = &source_unit.head { return_resolved_unit!(&head) }
+ if let Some(tail) = &source_unit.tail { return_resolved_unit!(&tail) }
return None;
}
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 {