diff --git a/Cargo.lock b/Cargo.lock index fc82d6570ab..688c29db4b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,12 +7,11 @@ dependencies = [ "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "multimap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "strings 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -58,7 +57,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -90,7 +89,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -103,14 +102,9 @@ name = "memchr" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "multimap" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "num-traits" version = "0.1.37" @@ -123,19 +117,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -154,12 +148,12 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -184,7 +178,7 @@ dependencies = [ "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -218,7 +212,7 @@ name = "syntex_errors" version = "0.58.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_pos 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -261,7 +255,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -278,7 +272,7 @@ name = "toml" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -340,18 +334,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "babb8281da88cba992fa1f4ddec7d63ed96280a1a53ec9b919fd37b53d71e502" +"checksum libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "e7eb6b826bfc1fdea7935d46556250d1799b7fe2d9f7951071f4291710665e3e" "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" -"checksum multimap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9223f4774d08e06185e44e555b9a7561243d387bac49c78a6205c42d6975fbf2" "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01" -"checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457" +"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" +"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" -"checksum serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "38a3db3a5757f68069aba764b793823ea9fb9717c42c016f8903f8add50f508a" -"checksum serde_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e46ef71ee001a4279a4513e79a6ebbb59da3a4987bf77a6df2e5534cd6f21d82" +"checksum serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c0c3d79316a6051231925504f6ef893d45088e8823c77a8331a3dcf427ee9087" +"checksum serde_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0019cd5b9f0529a1a0e145a912e9a2d60c325c58f7f260fc36c71976e9d76aee" "checksum serde_derive_internals 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "021c338d22c7e30f957a6ab7e388cb6098499dda9fd4ba1661ee074ca7a180d1" "checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b" "checksum strings 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da75d8bf2c4d210d63dd09581a041b036001f9f6e03d9b151dbff810fb7ba26a" diff --git a/Cargo.toml b/Cargo.toml index 1dd674204c8..414c45c887a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,6 @@ log = "0.3" env_logger = "0.4" getopts = "0.2" itertools = "0.5.8" -multimap = "0.3" [build-dependencies] walkdir = "1.0.3" diff --git a/src/file_lines.rs b/src/file_lines.rs index 9256f853f80..9de427781fe 100644 --- a/src/file_lines.rs +++ b/src/file_lines.rs @@ -11,18 +11,17 @@ //! This module contains types and functions to support formatting specific line ranges. use std::{cmp, iter, path, str}; +use std::collections::HashMap; -use itertools::Itertools; -use multimap::MultiMap; use serde_json as json; use codemap::LineRange; /// A range that is inclusive of both ends. -#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, Deserialize)] struct Range { - pub lo: usize, - pub hi: usize, + lo: usize, + hi: usize, } impl<'a> From<&'a LineRange> for Range { @@ -82,18 +81,30 @@ impl Range { /// non-overlapping ranges sorted by their start point. An inner `None` is interpreted to mean all /// lines in all files. #[derive(Clone, Debug, Default)] -pub struct FileLines(Option>); +pub struct FileLines(Option>>); /// Normalizes the ranges so that the invariants for `FileLines` hold: ranges are non-overlapping, /// and ordered by their start point. -fn normalize_ranges(map: &mut MultiMap) { - for (_, ranges) in map.iter_all_mut() { - ranges.sort_by_key(|x| x.lo); - let merged = ranges - .drain(..) - .coalesce(|x, y| x.merge(y).ok_or((x, y))) - .collect(); - *ranges = merged; +fn normalize_ranges(ranges: &mut HashMap>) { + for ranges in ranges.values_mut() { + ranges.sort(); + let mut result = vec![]; + { + let mut iter = ranges.into_iter().peekable(); + while let Some(next) = iter.next() { + let mut next = next.clone(); + while let Some(&&mut peek) = iter.peek() { + if let Some(merged) = next.merge(peek) { + iter.next().unwrap(); + next = merged; + } else { + break; + } + } + result.push(next) + } + } + *ranges = result; } } @@ -103,16 +114,14 @@ impl FileLines { FileLines(None) } - /// Creates a `FileLines` from a `MultiMap`, ensuring that the invariants hold. - fn from_multimap(map: MultiMap) -> FileLines { - let mut map = map; - normalize_ranges(&mut map); - FileLines(Some(map)) + fn from_ranges(mut ranges: HashMap>) -> FileLines { + normalize_ranges(&mut ranges); + FileLines(Some(ranges)) } /// Returns an iterator over the files contained in `self`. pub fn files(&self) -> Files { - Files(self.0.as_ref().map(MultiMap::keys)) + Files(self.0.as_ref().map(|m| m.keys())) } /// Returns true if `self` includes all lines in all files. Otherwise runs `f` on all ranges in @@ -127,9 +136,9 @@ impl FileLines { }; match canonicalize_path_string(file_name) - .and_then(|file| map.get_vec(&file).ok_or(())) { - Ok(ranges) => ranges.iter().any(f), - Err(_) => false, + .and_then(|file| map.get(&file)) { + Some(ranges) => ranges.iter().any(f), + None => false, } } @@ -165,14 +174,14 @@ impl<'a> iter::Iterator for Files<'a> { } } -fn canonicalize_path_string(s: &str) -> Result { +fn canonicalize_path_string(s: &str) -> Option { if s == "stdin" { - return Ok(s.to_string()); + return Some(s.to_string()); } match path::PathBuf::from(s).canonicalize() { - Ok(canonicalized) => canonicalized.to_str().map(|s| s.to_string()).ok_or(()), - _ => Err(()), + Ok(canonicalized) => canonicalized.to_str().map(|s| s.to_string()), + _ => None, } } @@ -182,10 +191,12 @@ impl str::FromStr for FileLines { fn from_str(s: &str) -> Result { let v: Vec = json::from_str(s).map_err(|e| e.to_string())?; - let m = v.into_iter() - .map(JsonSpan::into_tuple) - .collect::>()?; - Ok(FileLines::from_multimap(m)) + let mut m = HashMap::new(); + for js in v.into_iter() { + let (s, r) = JsonSpan::into_tuple(js)?; + m.entry(s).or_insert(vec![]).push(r); + } + Ok(FileLines::from_ranges(m)) } } @@ -197,11 +208,10 @@ struct JsonSpan { } impl JsonSpan { - // To allow `collect()`ing into a `MultiMap`. fn into_tuple(self) -> Result<(String, Range), String> { let (lo, hi) = self.range; let canonical = canonicalize_path_string(&self.file) - .map_err(|_| format!("Can't canonicalize {}", &self.file))?; + .ok_or_else(|| format!("Can't canonicalize {}", &self.file))?; Ok((canonical, Range::new(lo, hi))) } } diff --git a/src/lib.rs b/src/lib.rs index f31f3c0c3ee..477474df148 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,6 @@ extern crate regex; extern crate diff; extern crate term; extern crate itertools; -extern crate multimap; use errors::{Handler, DiagnosticBuilder}; use errors::emitter::{ColorConfig, EmitterWriter};