From f7bfe7f16c2230d894530f40e5f2d00d23899465 Mon Sep 17 00:00:00 2001 From: xd009642 Date: Wed, 8 Aug 2018 21:39:59 +0100 Subject: [PATCH 1/4] Moved source_analysis to Lines enum for positions Lines::Line(usize) and Lines::All now denote source positions. This is in part to allow ignoring of whole source files without storing and propagating up the file sizes and filling in a hashset with every line of the file. --- src/source_analysis.rs | 342 +++++++++++++++++++++++++---------------- 1 file changed, 208 insertions(+), 134 deletions(-) diff --git a/src/source_analysis.rs b/src/source_analysis.rs index 4fab3374c0..562b9ceb76 100644 --- a/src/source_analysis.rs +++ b/src/source_analysis.rs @@ -1,4 +1,5 @@ use std::path::{PathBuf, Path}; +use std::cell::Cell; use std::collections::{HashSet, HashMap}; use std::fs::File; use std::ffi::OsStr; @@ -10,15 +11,22 @@ use regex::Regex; use config::Config; use walkdir::{DirEntry, WalkDir}; +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum Lines { + All, + Line(usize), +} + /// Represents the results of analysis of a single file. Does not store the file /// in question as this is expected to be maintained by the user. #[derive(Clone, Debug)] pub struct LineAnalysis { /// This represents lines that should be ignored in coverage /// but may be identifed as coverable in the DWARF tables - pub ignore: HashSet, + pub ignore: HashSet, /// This represents lines that should be included in coverage - /// But may be ignored. + /// But may be ignored. Doesn't make sense to cover ALL the lines so this + /// is just an index. pub cover: HashSet, } @@ -39,7 +47,7 @@ impl SourceAnalysisQuery for HashMap { fn should_ignore(&self, path: &Path, l:&usize) -> bool { if self.contains_key(path) { - self.get(path).unwrap().ignore.contains(l) + self.get(path).unwrap().ignore.contains(&Lines::Line(*l)) } else { false } @@ -58,16 +66,21 @@ impl LineAnalysis { /// Adds the lines of the provided span to the ignore set pub fn ignore_span(&mut self, span: Span) { - for i in span.start().line..(span.end().line+1) { - self.ignore.insert(i); - if self.cover.contains(&i) { - self.cover.remove(&i); + // If we're already ignoring everything no need to ignore this span + if !self.ignore.contains(&Lines::All) { + for i in span.start().line..(span.end().line+1) { + self.ignore.insert(Lines::Line(i)); + if self.cover.contains(&i) { + self.cover.remove(&i); + } } } } /// Adds the lines of the provided span to the cover set pub fn cover_span(&mut self, span: Span, contents: Option<&str>) { + // Not checking for Lines::All because I trust we've called cover_span + // for a reason. let mut useful_lines: HashSet = HashSet::new(); if let Some(ref c) = contents { lazy_static! { @@ -97,7 +110,7 @@ impl LineAnalysis { } } for i in span.start().line..(span.end().line +1) { - if !self.ignore.contains(&i) && useful_lines.contains(&i) { + if !self.ignore.contains(&Lines::Line(i)) && useful_lines.contains(&i) { self.cover.insert(i); } } @@ -105,15 +118,17 @@ impl LineAnalysis { /// Shows whether the line should be ignored by tarpaulin pub fn should_ignore(&self, line: usize) -> bool { - self.ignore.contains(&line) + self.ignore.contains(&Lines::Line(line)) || self.ignore.contains(&Lines::All) } /// Adds a line to the list of lines to ignore fn add_to_ignore(&mut self, lines: &[usize]) { - for l in lines { - self.ignore.insert(*l); - if self.cover.contains(l) { - self.cover.remove(l); + if !self.ignore.contains(&Lines::All) { + for l in lines { + self.ignore.insert(Lines::Line(*l)); + if self.cover.contains(l) { + self.cover.remove(l); + } } } } @@ -134,6 +149,9 @@ fn is_target_folder(entry: &DirEntry, root: &Path) -> bool { /// Returns a list of files and line numbers to ignore (not indexes!) pub fn get_line_analysis(project: &Workspace, config: &Config) -> HashMap { let mut result: HashMap = HashMap::new(); + + let mut ignored_files: HashSet = HashSet::new(); + let walker = WalkDir::new(project.root()).into_iter(); for e in walker.filter_entry(|e| !is_target_folder(e, project.root())) .filter_map(|e| e.ok()) @@ -167,7 +185,10 @@ fn analyse_lib_rs(file: &Path, result: &mut HashMap) { /// config and the source code being analysed. struct Context<'a> { config: &'a Config, - file_contents: &'a str + file_contents: &'a str, + /// Other parts of context are immutable like tarpaulin config and users + /// source code. This is discovered during hence use of interior mutability + ignore_mods: Cell> } @@ -189,9 +210,10 @@ fn analyse_package(path: &Path, let file = parse_file(&content); if let Ok(file) = file { let mut analysis = LineAnalysis::new(); - let ctx = Context { + let mut ctx = Context { config, file_contents: &content, + ignore_mods: Cell::new(HashSet::new()), }; find_ignorable_lines(&content, &mut analysis); @@ -309,6 +331,7 @@ fn visit_mod(module: &ItemMod, analysis: &mut LineAnalysis, ctx: &Context) { } } } + //TODO here it goes if check_insides { if let Some((_, ref items)) = module.content { process_items(items, ctx, analysis); @@ -357,7 +380,8 @@ fn visit_fn(func: &ItemFn, analysis: &mut LineAnalysis, ctx: &Context) { return } visit_generics(&func.decl.generics, analysis); - analysis.ignore.remove(&func.decl.fn_token.span().start().line); + let line_number = func.decl.fn_token.span().start().line; + analysis.ignore.remove(&Lines::Line(line_number)); // Ignore multiple lines of fn decl let decl_start = func.decl.fn_token.0.start().line+1; let stmts_start = func.block.span().start().line; @@ -366,6 +390,7 @@ fn visit_fn(func: &ItemFn, analysis: &mut LineAnalysis, ctx: &Context) { } } + fn check_attr_list(attrs: &[Attribute], ctx: &Context) -> bool { let mut check_cover = true; for attr in attrs { @@ -427,7 +452,7 @@ fn visit_trait(trait_item: &ItemTrait, analysis: &mut LineAnalysis, ctx: &Contex if let Some(ref block) = i.default { analysis.cover_span(item.span(), Some(ctx.file_contents)); visit_generics(&i.sig.decl.generics, analysis); - analysis.ignore.remove(&i.sig.span().start().line); + analysis.ignore.remove(&Lines::Line(i.sig.span().start().line)); // Ignore multiple lines of fn decl let decl_start = i.sig.decl.fn_token.0.start().line+1; @@ -465,7 +490,7 @@ fn visit_impl(impl_blk: &ItemImpl, analysis: &mut LineAnalysis, ctx: &Context) { } visit_generics(&i.sig.decl.generics, analysis); - analysis.ignore.remove(&i.span().start().line); + analysis.ignore.remove(&Lines::Line(i.span().start().line)); // Ignore multiple lines of fn decl let decl_start = i.sig.decl.fn_token.0.start().line+1; @@ -803,32 +828,35 @@ mod tests { let ctx = Context { config: &config, file_contents: "fn test() {\nwriteln!(#\"test\n\ttest\n\ttest\"#);\n}\n", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); assert!(lines.ignore.len() > 1); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); let ctx = Context { config: &config, file_contents: "fn test() {\nwrite(\"test\ntest\ntest\");\n}\nfn write(s:&str){}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); let mut lines = LineAnalysis::new(); process_items(&parser.items, &ctx, &mut lines); assert!(lines.ignore.len() > 1); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); let mut lines = LineAnalysis::new(); let ctx = Context { config: &config, file_contents: "\n\nfn test() {\nwriteln!(\n#\"test\"#\n);\n}\n", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&5)); + assert!(lines.ignore.contains(&Lines::Line(5))); } #[test] @@ -838,24 +866,26 @@ mod tests { let ctx = Context { config: &config, file_contents: "#[derive(Debug)]\npub struct Struct {\npub i: i32,\nj:String,\n}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); assert!(lines.ignore.len()> 3); - assert!(lines.ignore.contains(&1)); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); + assert!(lines.ignore.contains(&Lines::Line(1))); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); let ctx = Context { config: &config, file_contents: "#[derive(Debug)]\npub struct Struct (\n i32\n);", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); assert!(!lines.ignore.is_empty()); - assert!(lines.ignore.contains(&3)); + assert!(lines.ignore.contains(&Lines::Line(3))); } #[test] @@ -865,16 +895,17 @@ mod tests { let ctx = Context { config: &config, file_contents: "#[derive(Debug)]\npub enum E {\nI1,\nI2(u32),\nI3{\nx:u32,\n},\n}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); assert!(lines.ignore.len()> 3); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); - assert!(lines.ignore.contains(&5)); - assert!(lines.ignore.contains(&6)); - assert!(lines.ignore.contains(&7)); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(5))); + assert!(lines.ignore.contains(&Lines::Line(6))); + assert!(lines.ignore.contains(&Lines::Line(7))); } #[test] @@ -890,11 +921,12 @@ mod tests { y:4, } }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&4)); - assert!(lines.ignore.contains(&5)); + assert!(!lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(5))); } #[test] @@ -903,29 +935,32 @@ mod tests { let ctx = Context { config: &config, file_contents: "mod foo {\nfn double(x:i32)->i32 {\n x*2\n}\n}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); let mut lines = LineAnalysis::new(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&3)); + assert!(!lines.ignore.contains(&Lines::Line(3))); let mut lines = LineAnalysis::new(); let ctx = Context { config: &config, file_contents: "mod foo;", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&1)); + assert!(lines.ignore.contains(&Lines::Line(1))); let mut lines = LineAnalysis::new(); let ctx = Context { config: &config, file_contents: "mod foo{}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&1)); + assert!(lines.ignore.contains(&Lines::Line(1))); } #[test] @@ -935,22 +970,24 @@ mod tests { let ctx = Context { config: &config, file_contents: "\n\nfn unused() {\nunimplemented!();\n}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); // Braces should be ignored so number could be higher assert!(lines.ignore.len() >= 1); - assert!(lines.ignore.contains(&4)); + assert!(lines.ignore.contains(&Lines::Line(4))); let mut lines = LineAnalysis::new(); let ctx = Context { config: &config, file_contents: "\n\nfn unused() {\nunreachable!();\n}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); assert!(lines.ignore.len() >= 1); - assert!(lines.ignore.contains(&4)); + assert!(lines.ignore.contains(&Lines::Line(4))); let mut lines = LineAnalysis::new(); let ctx = Context { @@ -961,20 +998,22 @@ mod tests { 2 => 7, _ => unreachable!(), } - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&5)); + assert!(lines.ignore.contains(&Lines::Line(5))); let mut lines = LineAnalysis::new(); let ctx = Context { config: &config, file_contents: "fn unused() {\nprintln!(\"text\");\n}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&2)); + assert!(!lines.ignore.contains(&Lines::Line(2))); } #[test] @@ -987,38 +1026,42 @@ mod tests { let ctx = Context { config: &config, file_contents: "#[cfg(test)]\nmod tests {\n fn boo(){\nassert!(true);\n}\n}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&4)); + assert!(!lines.ignore.contains(&Lines::Line(4))); let ctx = Context { config: &igconfig, file_contents: "#[cfg(test)]\nmod tests {\n fn boo(){\nassert!(true);\n}\n}", + ignore_mods: Cell::new(HashSet::new()), }; let mut lines = LineAnalysis::new(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&4)); + assert!(lines.ignore.contains(&Lines::Line(4))); let ctx = Context { config: &config, file_contents: "#[test]\nfn mytest() { \n assert!(true);\n}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); let mut lines = LineAnalysis::new(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&2)); - assert!(!lines.ignore.contains(&3)); + assert!(!lines.ignore.contains(&Lines::Line(2))); + assert!(!lines.ignore.contains(&Lines::Line(3))); let ctx = Context { config: &igconfig, file_contents: "#[test]\nfn mytest() { \n assert!(true);\n}", + ignore_mods: Cell::new(HashSet::new()), }; let mut lines = LineAnalysis::new(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&2)); - assert!(lines.ignore.contains(&3)); + assert!(lines.ignore.contains(&Lines::Line(2))); + assert!(lines.ignore.contains(&Lines::Line(3))); } @@ -1036,12 +1079,13 @@ mod tests { assert!(true); } }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&2)); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); + assert!(lines.ignore.contains(&Lines::Line(2))); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); let config = Config::default(); @@ -1054,11 +1098,12 @@ mod tests { assert!(true); } }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&3)); - assert!(!lines.ignore.contains(&4)); + assert!(!lines.ignore.contains(&Lines::Line(3))); + assert!(!lines.ignore.contains(&Lines::Line(4))); } @@ -1071,10 +1116,11 @@ mod tests { file_contents: "fn boop() -> T where T:Default { T::default() }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&1)); + assert!(!lines.ignore.contains(&Lines::Line(1))); let mut lines = LineAnalysis::new(); let ctx = Context { @@ -1083,10 +1129,11 @@ mod tests { where T:Default { T::default() }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&2)); + assert!(lines.ignore.contains(&Lines::Line(2))); let mut lines = LineAnalysis::new(); let ctx = Context { @@ -1097,10 +1144,11 @@ mod tests { T::default() } }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&3)); + assert!(lines.ignore.contains(&Lines::Line(3))); } @@ -1111,20 +1159,22 @@ mod tests { let ctx = Context { config: &config, file_contents: "#[derive(Debug)]\nstruct T;", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&1)); + assert!(lines.ignore.contains(&Lines::Line(1))); let mut lines = LineAnalysis::new(); let ctx = Context { config: &config, file_contents: "\n#[derive(Copy, Eq)]\nunion x { x:i32, y:f32}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&2)); + assert!(lines.ignore.contains(&Lines::Line(2))); } #[test] @@ -1134,20 +1184,22 @@ mod tests { let ctx = Context { config: &config, file_contents: "fn unsafe_fn() {\n let x=1;\nunsafe {\nprintln!(\"{}\", x);\n}\n}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&3)); - assert!(!lines.ignore.contains(&4)); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(!lines.ignore.contains(&Lines::Line(4))); let mut lines = LineAnalysis::new(); let ctx = Context { config: &config, file_contents: "fn unsafe_fn() {\n let x=1;\nunsafe {println!(\"{}\", x);}\n}", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&3)); + assert!(!lines.ignore.contains(&Lines::Line(3))); } #[test] @@ -1162,6 +1214,7 @@ mod tests { println!(\"hello world\"); } }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1179,6 +1232,7 @@ mod tests { } } }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1196,6 +1250,7 @@ mod tests { println!(\"hello world\"); } }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1231,11 +1286,12 @@ mod tests { &get_name() ); //20 }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&15)); - assert!(!lines.ignore.contains(&19)); + assert!(lines.ignore.contains(&Lines::Line(15))); + assert!(!lines.ignore.contains(&Lines::Line(19))); } #[test] @@ -1245,12 +1301,13 @@ mod tests { let ctx = Context { config: &config, file_contents: "use std::collections::HashMap; - use std::{ffi::CString, os::raw::c_char};" + use std::{ffi::CString, os::raw::c_char};", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&1)); - assert!(lines.ignore.contains(&2)); + assert!(lines.ignore.contains(&Lines::Line(1))); + assert!(lines.ignore.contains(&Lines::Line(2))); } #[test] @@ -1267,7 +1324,8 @@ mod tests { None of us should */ println!(\"But I will\"); - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1295,14 +1353,15 @@ mod tests { fn covered() { println!(\"hell world\"); } - " + ", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&2)); - assert!(lines.ignore.contains(&3)); - assert!(!lines.ignore.contains(&7)); - assert!(!lines.ignore.contains(&8)); + assert!(lines.ignore.contains(&Lines::Line(2))); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(!lines.ignore.contains(&Lines::Line(7))); + assert!(!lines.ignore.contains(&Lines::Line(8))); let mut lines = LineAnalysis::new(); let ctx = Context { @@ -1318,14 +1377,15 @@ mod tests { println!(\"hell world\"); } } - " + ", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); - assert!(lines.ignore.contains(&8)); - assert!(lines.ignore.contains(&9)); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(8))); + assert!(lines.ignore.contains(&Lines::Line(9))); } @@ -1346,14 +1406,15 @@ mod tests { println!(\"hell world\"); } } - " + ", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); - assert!(lines.ignore.contains(&8)); - assert!(lines.ignore.contains(&9)); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(8))); + assert!(lines.ignore.contains(&Lines::Line(9))); let mut lines = LineAnalysis::new(); let ctx = Context { @@ -1368,14 +1429,15 @@ mod tests { println!(\"hell world\"); } } - " + ", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&2)); - assert!(!lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&7)); - assert!(lines.ignore.contains(&8)); + assert!(!lines.ignore.contains(&Lines::Line(2))); + assert!(!lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(7))); + assert!(lines.ignore.contains(&Lines::Line(8))); } @@ -1397,14 +1459,15 @@ mod tests { println!(\"hell world\"); } } - " + ", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&4)); - assert!(lines.ignore.contains(&5)); - assert!(lines.ignore.contains(&9)); - assert!(lines.ignore.contains(&10)); + assert!(lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(5))); + assert!(lines.ignore.contains(&Lines::Line(9))); + assert!(lines.ignore.contains(&Lines::Line(10))); let mut lines = LineAnalysis::new(); let ctx = Context { @@ -1421,14 +1484,15 @@ mod tests { println!(\"hell world\"); } } - " + ", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&3)); - assert!(!lines.ignore.contains(&4)); - assert!(lines.ignore.contains(&9)); - assert!(lines.ignore.contains(&10)); + assert!(!lines.ignore.contains(&Lines::Line(3))); + assert!(!lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(9))); + assert!(lines.ignore.contains(&Lines::Line(10))); } @@ -1446,11 +1510,12 @@ mod tests { unreachable!(); }, } - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&6)); + assert!(lines.ignore.contains(&Lines::Line(6))); } #[test] @@ -1465,11 +1530,12 @@ mod tests { 2 => 7, _ => panic!(), } - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(!lines.ignore.contains(&5)); + assert!(!lines.ignore.contains(&Lines::Line(5))); let mut config = Config::default(); config.ignore_panics = true; @@ -1482,12 +1548,13 @@ mod tests { 2 => 7, _ => panic!(), } - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&5)); + assert!(lines.ignore.contains(&Lines::Line(5))); } #[test] @@ -1512,11 +1579,12 @@ mod tests { } } } - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&9)); + assert!(lines.ignore.contains(&Lines::Line(9))); } #[test] @@ -1529,12 +1597,13 @@ mod tests { y:u32, z:u32) { println!(\"{}:{}:{}\",x,y,z); - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&2)); - assert!(lines.ignore.contains(&3)); + assert!(lines.ignore.contains(&Lines::Line(2))); + assert!(lines.ignore.contains(&Lines::Line(3))); let mut lines = LineAnalysis::new(); let ctx = Context { @@ -1546,12 +1615,13 @@ mod tests { z:u32) { println!(\"{}:{}:{}\",x,y,z); } - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&4)); - assert!(lines.ignore.contains(&5)); + assert!(lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(5))); let mut lines = LineAnalysis::new(); let ctx = Context { @@ -1562,12 +1632,13 @@ mod tests { z:u32) { println!(\"{}:{}:{}\",x,y,z); } - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); } #[test] @@ -1580,14 +1651,15 @@ mod tests { fn empty_match(x: Void) -> u32 { match x { } - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&2)); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); - assert!(lines.ignore.contains(&5)); + assert!(lines.ignore.contains(&Lines::Line(2))); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(5))); let mut lines = LineAnalysis::new(); let ctx = Context { @@ -1603,16 +1675,17 @@ mod tests { } else { call(); } - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); - assert!(lines.ignore.contains(&5)); - assert!(lines.ignore.contains(&6)); - assert!(lines.ignore.contains(&7)); - assert!(lines.ignore.contains(&8)); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(5))); + assert!(lines.ignore.contains(&Lines::Line(6))); + assert!(lines.ignore.contains(&Lines::Line(7))); + assert!(lines.ignore.contains(&Lines::Line(8))); let mut lines = LineAnalysis::new(); let ctx = Context { @@ -1623,17 +1696,18 @@ mod tests { bar(); } unreachable!(); - }" + }", + ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); - assert!(lines.ignore.contains(&1)); - assert!(lines.ignore.contains(&2)); - assert!(lines.ignore.contains(&3)); - assert!(lines.ignore.contains(&4)); - assert!(lines.ignore.contains(&5)); - assert!(lines.ignore.contains(&6)); - assert!(lines.ignore.contains(&7)); + assert!(lines.ignore.contains(&Lines::Line(1))); + assert!(lines.ignore.contains(&Lines::Line(2))); + assert!(lines.ignore.contains(&Lines::Line(3))); + assert!(lines.ignore.contains(&Lines::Line(4))); + assert!(lines.ignore.contains(&Lines::Line(5))); + assert!(lines.ignore.contains(&Lines::Line(6))); + assert!(lines.ignore.contains(&Lines::Line(7))); } } From 4a49d58731250b76e3830f1e01b043a84ff701c4 Mon Sep 17 00:00:00 2001 From: xd009642 Date: Wed, 8 Aug 2018 23:16:14 +0100 Subject: [PATCH 2/4] Added file path to context --- src/source_analysis.rs | 54 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/source_analysis.rs b/src/source_analysis.rs index 562b9ceb76..552b78498b 100644 --- a/src/source_analysis.rs +++ b/src/source_analysis.rs @@ -184,8 +184,12 @@ fn analyse_lib_rs(file: &Path, result: &mut HashMap) { /// Provides context to the source analysis stage including the tarpaulin /// config and the source code being analysed. struct Context<'a> { + /// Program config config: &'a Config, + /// Contents of the source file file_contents: &'a str, + /// path to the file being analysed + file: &'a Path, /// Other parts of context are immutable like tarpaulin config and users /// source code. This is discovered during hence use of interior mutability ignore_mods: Cell> @@ -213,6 +217,7 @@ fn analyse_package(path: &Path, let mut ctx = Context { config, file_contents: &content, + file: path, ignore_mods: Cell::new(HashSet::new()), }; @@ -828,6 +833,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "fn test() {\nwriteln!(#\"test\n\ttest\n\ttest\"#);\n}\n", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -839,6 +845,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "fn test() {\nwrite(\"test\ntest\ntest\");\n}\nfn write(s:&str){}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -852,6 +859,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "\n\nfn test() {\nwriteln!(\n#\"test\"#\n);\n}\n", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -866,6 +874,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "#[derive(Debug)]\npub struct Struct {\npub i: i32,\nj:String,\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -879,6 +888,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "#[derive(Debug)]\npub struct Struct (\n i32\n);", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -895,6 +905,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "#[derive(Debug)]\npub enum E {\nI1,\nI2(u32),\nI3{\nx:u32,\n},\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -921,6 +932,7 @@ mod tests { y:4, } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -935,6 +947,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "mod foo {\nfn double(x:i32)->i32 {\n x*2\n}\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -946,6 +959,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "mod foo;", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -956,6 +970,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "mod foo{}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -970,6 +985,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "\n\nfn unused() {\nunimplemented!();\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -982,6 +998,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "\n\nfn unused() {\nunreachable!();\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -999,6 +1016,7 @@ mod tests { _ => unreachable!(), } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1009,6 +1027,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "fn unused() {\nprintln!(\"text\");\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1026,6 +1045,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "#[cfg(test)]\nmod tests {\n fn boo(){\nassert!(true);\n}\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1035,6 +1055,7 @@ mod tests { let ctx = Context { config: &igconfig, file_contents: "#[cfg(test)]\nmod tests {\n fn boo(){\nassert!(true);\n}\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; @@ -1045,6 +1066,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "#[test]\nfn mytest() { \n assert!(true);\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1056,6 +1078,7 @@ mod tests { let ctx = Context { config: &igconfig, file_contents: "#[test]\nfn mytest() { \n assert!(true);\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let mut lines = LineAnalysis::new(); @@ -1079,6 +1102,7 @@ mod tests { assert!(true); } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1098,6 +1122,7 @@ mod tests { assert!(true); } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1116,6 +1141,7 @@ mod tests { file_contents: "fn boop() -> T where T:Default { T::default() }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1129,6 +1155,7 @@ mod tests { where T:Default { T::default() }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1144,6 +1171,7 @@ mod tests { T::default() } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1159,6 +1187,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "#[derive(Debug)]\nstruct T;", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1170,6 +1199,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "\n#[derive(Copy, Eq)]\nunion x { x:i32, y:f32}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1184,6 +1214,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "fn unsafe_fn() {\n let x=1;\nunsafe {\nprintln!(\"{}\", x);\n}\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1195,6 +1226,7 @@ mod tests { let ctx = Context { config: &config, file_contents: "fn unsafe_fn() {\n let x=1;\nunsafe {println!(\"{}\", x);}\n}", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1214,6 +1246,7 @@ mod tests { println!(\"hello world\"); } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1232,6 +1265,7 @@ mod tests { } } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1250,6 +1284,7 @@ mod tests { println!(\"hello world\"); } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1286,6 +1321,7 @@ mod tests { &get_name() ); //20 }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1302,6 +1338,7 @@ mod tests { config: &config, file_contents: "use std::collections::HashMap; use std::{ffi::CString, os::raw::c_char};", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1325,6 +1362,7 @@ mod tests { */ println!(\"But I will\"); }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1354,6 +1392,7 @@ mod tests { println!(\"hell world\"); } ", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1378,6 +1417,7 @@ mod tests { } } ", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1407,6 +1447,7 @@ mod tests { } } ", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1430,6 +1471,7 @@ mod tests { } } ", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1460,6 +1502,7 @@ mod tests { } } ", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1485,6 +1528,7 @@ mod tests { } } ", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1511,6 +1555,7 @@ mod tests { }, } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1531,6 +1576,7 @@ mod tests { _ => panic!(), } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1549,6 +1595,7 @@ mod tests { _ => panic!(), } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; @@ -1580,6 +1627,7 @@ mod tests { } } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1598,6 +1646,7 @@ mod tests { z:u32) { println!(\"{}:{}:{}\",x,y,z); }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1616,6 +1665,7 @@ mod tests { println!(\"{}:{}:{}\",x,y,z); } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1633,6 +1683,7 @@ mod tests { println!(\"{}:{}:{}\",x,y,z); } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1652,6 +1703,7 @@ mod tests { match x { } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1676,6 +1728,7 @@ mod tests { call(); } }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1697,6 +1750,7 @@ mod tests { } unreachable!(); }", + file: Path::new(""), ignore_mods: Cell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); From 9dabe3154a9ee01cfcfaf97ca2e3de7eed9ed2cb Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sat, 11 Aug 2018 16:02:17 +0100 Subject: [PATCH 3/4] Switch to RefCell. Add ignored files to list. Just need to integrate and test. --- src/source_analysis.rs | 107 +++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/src/source_analysis.rs b/src/source_analysis.rs index 552b78498b..20aaf377c3 100644 --- a/src/source_analysis.rs +++ b/src/source_analysis.rs @@ -1,5 +1,5 @@ use std::path::{PathBuf, Path}; -use std::cell::Cell; +use std::cell::RefCell; use std::collections::{HashSet, HashMap}; use std::fs::File; use std::ffi::OsStr; @@ -192,7 +192,7 @@ struct Context<'a> { file: &'a Path, /// Other parts of context are immutable like tarpaulin config and users /// source code. This is discovered during hence use of interior mutability - ignore_mods: Cell> + ignore_mods: RefCell> } @@ -218,7 +218,7 @@ fn analyse_package(path: &Path, config, file_contents: &content, file: path, - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; find_ignorable_lines(&content, &mut analysis); @@ -341,6 +341,9 @@ fn visit_mod(module: &ItemMod, analysis: &mut LineAnalysis, ctx: &Context) { if let Some((_, ref items)) = module.content { process_items(items, ctx, analysis); } + } else { + ctx.ignore_mods.borrow_mut().insert(ctx.file.join(module.ident.to_string())); + } } @@ -834,7 +837,7 @@ mod tests { config: &config, file_contents: "fn test() {\nwriteln!(#\"test\n\ttest\n\ttest\"#);\n}\n", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -846,7 +849,7 @@ mod tests { config: &config, file_contents: "fn test() {\nwrite(\"test\ntest\ntest\");\n}\nfn write(s:&str){}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); let mut lines = LineAnalysis::new(); @@ -860,7 +863,7 @@ mod tests { config: &config, file_contents: "\n\nfn test() {\nwriteln!(\n#\"test\"#\n);\n}\n", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -875,7 +878,7 @@ mod tests { config: &config, file_contents: "#[derive(Debug)]\npub struct Struct {\npub i: i32,\nj:String,\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -889,7 +892,7 @@ mod tests { config: &config, file_contents: "#[derive(Debug)]\npub struct Struct (\n i32\n);", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -906,7 +909,7 @@ mod tests { config: &config, file_contents: "#[derive(Debug)]\npub enum E {\nI1,\nI2(u32),\nI3{\nx:u32,\n},\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -933,7 +936,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -948,7 +951,7 @@ mod tests { config: &config, file_contents: "mod foo {\nfn double(x:i32)->i32 {\n x*2\n}\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); let mut lines = LineAnalysis::new(); @@ -960,7 +963,7 @@ mod tests { config: &config, file_contents: "mod foo;", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -971,7 +974,7 @@ mod tests { config: &config, file_contents: "mod foo{}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -986,7 +989,7 @@ mod tests { config: &config, file_contents: "\n\nfn unused() {\nunimplemented!();\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -999,7 +1002,7 @@ mod tests { config: &config, file_contents: "\n\nfn unused() {\nunreachable!();\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1017,7 +1020,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1028,7 +1031,7 @@ mod tests { config: &config, file_contents: "fn unused() {\nprintln!(\"text\");\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1046,7 +1049,7 @@ mod tests { config: &config, file_contents: "#[cfg(test)]\nmod tests {\n fn boo(){\nassert!(true);\n}\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1056,7 +1059,7 @@ mod tests { config: &igconfig, file_contents: "#[cfg(test)]\nmod tests {\n fn boo(){\nassert!(true);\n}\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let mut lines = LineAnalysis::new(); @@ -1067,7 +1070,7 @@ mod tests { config: &config, file_contents: "#[test]\nfn mytest() { \n assert!(true);\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); let mut lines = LineAnalysis::new(); @@ -1079,7 +1082,7 @@ mod tests { config: &igconfig, file_contents: "#[test]\nfn mytest() { \n assert!(true);\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let mut lines = LineAnalysis::new(); process_items(&parser.items, &ctx, &mut lines); @@ -1103,7 +1106,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1123,7 +1126,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1142,7 +1145,7 @@ mod tests { T::default() }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1156,7 +1159,7 @@ mod tests { T::default() }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1172,7 +1175,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1188,7 +1191,7 @@ mod tests { config: &config, file_contents: "#[derive(Debug)]\nstruct T;", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1200,7 +1203,7 @@ mod tests { config: &config, file_contents: "\n#[derive(Copy, Eq)]\nunion x { x:i32, y:f32}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1215,7 +1218,7 @@ mod tests { config: &config, file_contents: "fn unsafe_fn() {\n let x=1;\nunsafe {\nprintln!(\"{}\", x);\n}\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1227,7 +1230,7 @@ mod tests { config: &config, file_contents: "fn unsafe_fn() {\n let x=1;\nunsafe {println!(\"{}\", x);}\n}", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1247,7 +1250,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1266,7 +1269,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1285,7 +1288,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1322,7 +1325,7 @@ mod tests { ); //20 }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1339,7 +1342,7 @@ mod tests { file_contents: "use std::collections::HashMap; use std::{ffi::CString, os::raw::c_char};", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1363,7 +1366,7 @@ mod tests { println!(\"But I will\"); }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1393,7 +1396,7 @@ mod tests { } ", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1418,7 +1421,7 @@ mod tests { } ", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1448,7 +1451,7 @@ mod tests { } ", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1472,7 +1475,7 @@ mod tests { } ", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1503,7 +1506,7 @@ mod tests { } ", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1529,7 +1532,7 @@ mod tests { } ", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1556,7 +1559,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1577,7 +1580,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1596,7 +1599,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); @@ -1628,7 +1631,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1647,7 +1650,7 @@ mod tests { println!(\"{}:{}:{}\",x,y,z); }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1666,7 +1669,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1684,7 +1687,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1704,7 +1707,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1729,7 +1732,7 @@ mod tests { } }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); @@ -1751,7 +1754,7 @@ mod tests { unreachable!(); }", file: Path::new(""), - ignore_mods: Cell::new(HashSet::new()), + ignore_mods: RefCell::new(HashSet::new()), }; let parser = parse_file(ctx.file_contents).unwrap(); process_items(&parser.items, &ctx, &mut lines); From 1da983bc300d7257fdaea521e7effd92885f264a Mon Sep 17 00:00:00 2001 From: xd009642 Date: Sun, 12 Aug 2018 12:39:55 +0100 Subject: [PATCH 4/4] Changes integrated in. Fixed not popping current filename off file cause main.rs/my_mod.rs issue. Updated the SourceAnalysis to add in the new information and tested on a simple example. --- src/source_analysis.rs | 51 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/src/source_analysis.rs b/src/source_analysis.rs index 20aaf377c3..f64709ecda 100644 --- a/src/source_analysis.rs +++ b/src/source_analysis.rs @@ -47,7 +47,7 @@ impl SourceAnalysisQuery for HashMap { fn should_ignore(&self, path: &Path, l:&usize) -> bool { if self.contains_key(path) { - self.get(path).unwrap().ignore.contains(&Lines::Line(*l)) + self.get(path).unwrap().should_ignore(*l) } else { false } @@ -64,6 +64,12 @@ impl LineAnalysis { } } + pub fn ignore_all(&mut self) { + self.ignore.clear(); + self.cover.clear(); + self.ignore.insert(Lines::All); + } + /// Adds the lines of the provided span to the ignore set pub fn ignore_span(&mut self, span: Span) { // If we're already ignoring everything no need to ignore this span @@ -156,7 +162,19 @@ pub fn get_line_analysis(project: &Workspace, config: &Config) -> HashMap { fn analyse_package(path: &Path, root: &Path, config:&Config, - result: &mut HashMap) { + result: &mut HashMap, + filtered_files: &mut HashSet) { if let Some(file) = path.to_str() { let skip_cause_test = config.ignore_tests && @@ -225,6 +244,19 @@ fn analyse_package(path: &Path, process_items(&file.items, &ctx, &mut analysis); // Check there's no conflict! result.insert(path.to_path_buf(), analysis); + + let mut ignored_files = ctx.ignore_mods.into_inner(); + for f in ignored_files.drain() { + if f.is_file() { + filtered_files.insert(f); + } else { + let walker = WalkDir::new(f).into_iter(); + for e in walker.filter_map(|e| e.ok()) + .filter(|e| is_source_file(e)) { + filtered_files.insert(e.path().to_path_buf()); + } + } + } // This could probably be done with the DWARF if I could find a discriminating factor // to why lib.rs:1 shows up as a real line! if path.ends_with("src/lib.rs") { @@ -336,14 +368,21 @@ fn visit_mod(module: &ItemMod, analysis: &mut LineAnalysis, ctx: &Context) { } } } - //TODO here it goes if check_insides { if let Some((_, ref items)) = module.content { process_items(items, ctx, analysis); } } else { - ctx.ignore_mods.borrow_mut().insert(ctx.file.join(module.ident.to_string())); - + // Get the file or directory name of the module + let mut p = if let Some(parent) = ctx.file.parent() { + parent.join(module.ident.to_string()) + } else { + PathBuf::from(module.ident.to_string()) + }; + if !p.exists() { + p.set_extension("rs"); + } + ctx.ignore_mods.borrow_mut().insert(p); } }