From 7509901fa0985f8fc4893a83e0275a063f072dda Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Dec 2018 12:29:14 +0300 Subject: wip --- Cargo.lock | 358 +++++++++++++++++++++------------------- crates/ra_lsp_server/Cargo.toml | 2 +- crates/ra_vfs/Cargo.toml | 11 ++ crates/ra_vfs/src/arena.rs | 48 ++++++ crates/ra_vfs/src/io.rs | 72 ++++++++ crates/ra_vfs/src/lib.rs | 128 ++++++++++++++ 6 files changed, 452 insertions(+), 167 deletions(-) create mode 100644 crates/ra_vfs/Cargo.toml create mode 100644 crates/ra_vfs/src/arena.rs create mode 100644 crates/ra_vfs/src/io.rs create mode 100644 crates/ra_vfs/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 522550eb5..38307ff69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "aho-corasick" version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -21,10 +21,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayvec" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -32,30 +32,36 @@ name = "atty" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "autocfg" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "backtrace" -version = "0.3.9" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace-sys" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -93,19 +99,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo_metadata" -version = "0.6.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -120,7 +126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -150,11 +156,11 @@ name = "crossbeam-channel" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -171,23 +177,23 @@ name = "crossbeam-epoch" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -206,14 +212,22 @@ name = "crossbeam-utils" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "crossbeam-utils" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "derive-new" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -249,7 +263,7 @@ name = "error-chain" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -257,7 +271,7 @@ name = "failure" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -266,9 +280,9 @@ name = "failure_derive" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -279,18 +293,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "flexi_logger" -version = "0.10.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fst" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -319,9 +333,9 @@ dependencies = [ "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "languageserver-types 0.53.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -339,7 +353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "heck" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -381,7 +395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "itertools" -version = "0.7.8" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -405,9 +419,9 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -419,15 +433,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.43" +version = "0.2.45" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lock_api" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -451,11 +465,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -464,7 +478,7 @@ name = "memmap" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -475,7 +489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "nodrop" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -484,9 +498,9 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -504,15 +518,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "owning_ref" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -523,7 +537,7 @@ name = "parking_lot" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -532,10 +546,10 @@ name = "parking_lot_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -568,8 +582,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "pest 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "pest_meta 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -585,7 +599,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.4.20" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -593,17 +607,17 @@ dependencies = [ [[package]] name = "quote" -version = "0.6.9" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ra_analysis" version = "0.1.0" dependencies = [ - "fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fst 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "ra_db 0.1.0", @@ -647,7 +661,7 @@ dependencies = [ name = "ra_editor" version = "0.1.0" dependencies = [ - "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "join_to_string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "ra_syntax 0.1.0", "ra_text_edit 0.1.0", @@ -676,12 +690,12 @@ dependencies = [ name = "ra_lsp_server" version = "0.1.0" dependencies = [ - "cargo_metadata 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "flexi_logger 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "gen_lsp_server 0.1.0", "im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "languageserver-types 0.53.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -693,9 +707,9 @@ dependencies = [ "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", "smol_str 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "test_utils 0.1.0", @@ -703,23 +717,23 @@ dependencies = [ "thread_worker 0.1.0", "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ra_syntax" version = "0.1.0" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "ra_text_edit 0.1.0", - "rowan 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rowan 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "test_utils 0.1.0", "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -730,13 +744,23 @@ dependencies = [ "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ra_vfs" +version = "0.1.0" +dependencies = [ + "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -747,7 +771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -782,13 +806,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" -version = "0.1.40" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -796,27 +820,27 @@ name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "1.0.6" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -839,12 +863,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rowan" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -854,7 +878,7 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -875,7 +899,7 @@ dependencies = [ [[package]] name = "ryu" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -890,11 +914,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -916,7 +940,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -926,30 +950,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.80" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.80" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -973,7 +997,7 @@ dependencies = [ [[package]] name = "smallvec" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -984,7 +1008,7 @@ name = "smol_str" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1007,18 +1031,18 @@ name = "syn" version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "0.15.18" +version = "0.15.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1027,9 +1051,9 @@ name = "synstructure" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1044,7 +1068,7 @@ dependencies = [ [[package]] name = "tera" -version = "0.11.19" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1054,9 +1078,9 @@ dependencies = [ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "pest 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", "slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1068,9 +1092,9 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "ron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tera 0.11.19 (registry+https://github.com/rust-lang/crates.io-index)", + "tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1078,8 +1102,8 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1088,8 +1112,8 @@ name = "test_utils" version = "0.1.0" dependencies = [ "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1098,7 +1122,7 @@ name = "text_unit" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1131,16 +1155,16 @@ name = "threadpool" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "time" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1150,9 +1174,9 @@ version = "0.1.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1167,7 +1191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ucd-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1265,7 +1289,7 @@ name = "url_serde" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1291,7 +1315,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "walkdir" -version = "2.2.6" +version = "2.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1330,17 +1354,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" +"checksum arrayvec 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d18513977c2d8261c448511c5c53dc66b26dfccbc3d4446672dea1e71a7d8a26" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" -"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" +"checksum autocfg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e5f34df7a019573fb8bdc7e24a2bfebe51a2a1d6bfdbaeccedb3c41fc574727" +"checksum backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b5b493b66e03090ebc4343eb02f94ff944e0cbc9ac6571491d170ba026741eb5" +"checksum backtrace-sys 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3fcce89e5ad5c8949caa9434501f7b55415b3e7ad5270cb88c75a8d35e8f1279" "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" -"checksum cargo_metadata 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1aaa1a9856ae2d188340526d0986feb6899c9ad11c5dfd73453c784fed6e373d" -"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" +"checksum cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1b4d380e1bab994591a24c2bdd1b054f64b60bef483a8c598c7c345bc3bbe" +"checksum cc 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "155ed195f7bd722d1dfeb30365b9d0c1f6a078fa7ca4014497e5935d90993d6f" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" @@ -1348,9 +1373,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416" +"checksum crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" +"checksum crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "41ee4864f4797060e52044376f7d107429ce1fb43460021b126424b7180ee21a" "checksum derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c" "checksum deunicode 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" @@ -1361,37 +1387,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7" "checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -"checksum flexi_logger 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "553854ebfebeae44ba699a9dc7d53a4036ccc01cd1e144aea0e3054c54383733" -"checksum fst 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9b0408ab57c1bf7c634b2ac6a165d14f642dc3335a43203090a7f8c78b54577b" +"checksum flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4dda06444ccc8b0a6da19d939989b4a4e83f328710ada449eedaed48c8b903cd" +"checksum fst 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "db72126ca7dff566cdbbdd54af44668c544897d9d3862b198141f176f1238bdf" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" +"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" "checksum id-arena 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a7250033feafee46a1cecd2c2616a64aec1d064f38c9ae2bdd297728542843e" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9c7f9bb8aee47fc16d535a705f7867a9fc83bb822e5e1043bb98e77ffeed3c" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" -"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450" +"checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum join_to_string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7bddc885f3fd69dd4b5d747c2efe6dd2c36d795ea9938281ed50910e32c95e31" "checksum languageserver-types 0.53.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0be4f8f783832a308975035043c0e8ad18e11c3f3d395aa6f1a9f3a30b8e654" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" -"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a" +"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74" +"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16" +"checksum memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db4c41318937f6e76648f42826b1d9ade5c09cafb5aef7e351240a70f39206e9" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum num-derive 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238" +"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" @@ -1399,57 +1425,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b76f477146419bc539a63f4ef40e902166cb43b3e51cecc71d9136fd12c567e7" "checksum pest_generator 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ebee4e9680be4fd162e6f3394ae4192a6b60b1e4d17d845e631f0c68d1a3386" "checksum pest_meta 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1f6d5f6f0e6082578c86af197d780dc38328e3f768cec06aac9bc46d714e8221" -"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" -"checksum quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "63b5829244f52738cfee93b3a165c1911388675be000c888d2fae620dee8fa5b" +"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" +"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" "checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" "checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" "checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" -"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" +"checksum redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bcd297b87a545980a2d25a0beb72a1f490c31f0a9fde52fca35bfbb1ceb70" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ee84f70c8c08744ea9641a731c7fadb475bf2ecc52d7f627feb833e0b3990467" -"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" +"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" +"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1" "checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum ron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c48677d8a9247a4e0d1f3f9cb4b0a8e29167fdc3c04f383a5e669cd7a960ae0f" -"checksum rowan 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "795b1c830f5335e89f93415315518e9727307308c44c1e5adebe8a38f856c334" -"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" +"checksum rowan 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9ccca91953e9c549cac18e8f41daa5d49dad1c9a4c9bb977ac42718bb34e1bf" +"checksum rustc-demangle 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "01b90379b8664dd83460d59bdc5dd1fd3172b8913788db483ed1325171eab2f7" "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" +"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum salsa 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e56b13ce9b2bfaa1c89863d76880838c0734de85beeaef437fd70d4fa7e253d3" "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef" -"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c" -"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce" +"checksum serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)" = "6fa52f19aee12441d5ad11c9a00459122bd8f98707cadf9778c540674f1935b6" +"checksum serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)" = "96a7f9496ac65a2db5929afa087b54f8fc5008dcfbe48a8874ed20049b0d6154" +"checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811" "checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded" "checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" -"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" +"checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db" "checksum smol_str 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ed6f19b800d76574926e458d5f8e2dbea86c2b58c08d33a982448f09ac8d0c" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum superslice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b50b13d42370e0f5fc62eafdd5c2d20065eaf5458dab215ff3e20e63eea96b30" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)" = "90c39a061e2f412a9f869540471ab679e85e50c6b05604daf28bc3060f75c430" +"checksum syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9545a6a093a3f0bd59adb472700acc08cad3776f860f16a897dfce8c88721cbc" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -"checksum tera 0.11.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac6d8ad623a7efcfb4367ce2a36f84ef849d5aa3c7bcf2e0324c4cbcc57ebaf" +"checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3" "checksum teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d89ad4617d1dec55331067fadaa041e813479e1779616f3d3ce9308bf46184e" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8009d7bdbd896a7e09b595f8f9325a19047fc708653e60d0895202b82135048f" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" -"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" +"checksum time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "847da467bf0db05882a9e2375934a8a55cffdc9db0d128af1518200260ba1f6c" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77" -"checksum ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0f8bfa9ff0cadcd210129ad9d2c5f145c13e9ced3d3e5d948a6213487d52444" +"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum unic-char-property 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce36d3f7ce754afdbccccf8ff0dd0134e50fb44aaae579f96218856e9e5dbd1e" "checksum unic-char-range 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab85fab42ad1b26cafc03bf891f69cb4d6e15f491030e89a0122197baa8ae8" "checksum unic-common 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff8d4a7ade929ef7d971e16ced21a8cd56a63869aa6032dfb8cb083cf7d077bf" @@ -1468,7 +1494,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0ffb549f212c31e19f3667c55a7f515b983a84aef10fd0a4d1f9c125425115f3" +"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index ce4f79d46..4e8e09584 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml @@ -19,7 +19,7 @@ flexi_logger = "0.10.0" log = "0.4.3" url_serde = "0.2.0" languageserver-types = "0.53.0" -walkdir = "2.2.0" +walkdir = "2.2.7" im = "12.0.0" cargo_metadata = "0.6.0" text_unit = { version = "0.1.2", features = ["serde"] } diff --git a/crates/ra_vfs/Cargo.toml b/crates/ra_vfs/Cargo.toml new file mode 100644 index 000000000..f8d49b3f5 --- /dev/null +++ b/crates/ra_vfs/Cargo.toml @@ -0,0 +1,11 @@ +[package] +edition = "2018" +name = "ra_vfs" +version = "0.1.0" +authors = ["Aleksey Kladov "] + +[dependencies] +walkdir = "2.2.7" +relative-path = "0.4.0" +rustc-hash = "1.0" +crossbeam-channel = "0.2.4" diff --git a/crates/ra_vfs/src/arena.rs b/crates/ra_vfs/src/arena.rs new file mode 100644 index 000000000..d6fad753b --- /dev/null +++ b/crates/ra_vfs/src/arena.rs @@ -0,0 +1,48 @@ +use std::{ + hash::{Hash, Hasher}, + marker::PhantomData, + ops::{Index, IndexMut}, +}; + +#[derive(Clone, Debug)] +pub(crate) struct Arena { + data: Vec, + _ty: PhantomData, +} + +pub(crate) trait ArenaId { + fn from_u32(id: u32) -> Self; + fn to_u32(self) -> u32; +} + +impl Arena { + pub fn alloc(&mut self, value: T) -> ID { + let id = self.data.len() as u32; + self.data.push(value); + ID::from_u32(id) + } +} + +impl Default for Arena { + fn default() -> Arena { + Arena { + data: Vec::new(), + _ty: PhantomData, + } + } +} + +impl Index for Arena { + type Output = T; + fn index(&self, idx: ID) -> &T { + let idx = idx.to_u32() as usize; + &self.data[idx] + } +} + +impl IndexMut for Arena { + fn index_mut(&mut self, idx: ID) -> &mut T { + let idx = idx.to_u32() as usize; + &mut self.data[idx] + } +} diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs new file mode 100644 index 000000000..f90fe0e84 --- /dev/null +++ b/crates/ra_vfs/src/io.rs @@ -0,0 +1,72 @@ +use std::{ + fs, + path::{Path, PathBuf}, + thread::JoinHandle, +}; + +use walkdir::WalkDir; +use crossbeam_channel::{Sender, Receiver}; + +pub(crate) fn start_io() -> (JoinHandle<(), Sender<()>, Receiver()>) {} + +// use crate::thread_watcher::{ThreadWatcher, Worker}; + +// #[derive(Debug)] +// pub struct FileEvent { +// pub path: PathBuf, +// pub kind: FileEventKind, +// } + +// #[derive(Debug)] +// pub enum FileEventKind { +// Add(String), +// } + +// pub fn roots_loader() -> (Worker)>, ThreadWatcher) { +// Worker::)>::spawn( +// "roots loader", +// 128, +// |input_receiver, output_sender| { +// input_receiver +// .map(|path| { +// log::debug!("loading {} ...", path.as_path().display()); +// let events = load_root(path.as_path()); +// log::debug!("... loaded {}", path.as_path().display()); +// (path, events) +// }) +// .for_each(|it| output_sender.send(it)) +// }, +// ) +// } + +// fn load_root(path: &Path) -> Vec { +// let mut res = Vec::new(); +// for entry in WalkDir::new(path) { +// let entry = match entry { +// Ok(entry) => entry, +// Err(e) => { +// log::warn!("watcher error: {}", e); +// continue; +// } +// }; +// if !entry.file_type().is_file() { +// continue; +// } +// let path = entry.path(); +// if path.extension().and_then(|os| os.to_str()) != Some("rs") { +// continue; +// } +// let text = match fs::read_to_string(path) { +// Ok(text) => text, +// Err(e) => { +// log::warn!("watcher error: {}", e); +// continue; +// } +// }; +// res.push(FileEvent { +// path: path.to_owned(), +// kind: FileEventKind::Add(text), +// }) +// } +// res +// } diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs new file mode 100644 index 000000000..8f6abadb7 --- /dev/null +++ b/crates/ra_vfs/src/lib.rs @@ -0,0 +1,128 @@ +//! VFS stands for Virtual File System. +//! +//! When doing analysis, we don't want to do any IO, we want to keep all source +//! code in memory. However, the actual source code is stored on disk, so you +//! need to get it into the memory in the first place somehow. VFS is the +//! component which does this. +//! +//! It also is responsible for watching the disk for changes, and for merging +//! editor state (modified, unsaved files) with disk state. +//! +//! VFS is based on a concept of roots: a set of directories on the file system +//! whihc are watched for changes. Typically, there will be a root for each +//! Cargo package. +mod arena; +mod io; + +use std::{ + cmp::Reverse, + path::{Path, PathBuf}, + ffi::OsStr, + sync::Arc, +}; + +use relative_path::RelativePathBuf; +use crate::arena::{ArenaId, Arena}; + +/// `RootFilter` is a predicate that checks if a file can belong to a root +struct RootFilter { + root: PathBuf, + file_filter: fn(&Path) -> bool, +} + +impl RootFilter { + fn new(root: PathBuf) -> RootFilter { + RootFilter { + root, + file_filter: rs_extension_filter, + } + } + fn can_contain(&self, path: &Path) -> bool { + (self.file_filter)(path) && path.starts_with(&self.root) + } +} + +fn rs_extension_filter(p: &Path) -> bool { + p.extension() == Some(OsStr::new("rs")) +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +pub struct VfsRoot(u32); + +impl ArenaId for VfsRoot { + fn from_u32(idx: u32) -> VfsRoot { + VfsRoot(idx) + } + fn to_u32(self) -> u32 { + self.0 + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +pub struct VfsFile(u32); + +impl ArenaId for VfsFile { + fn from_u32(idx: u32) -> VfsFile { + VfsFile(idx) + } + fn to_u32(self) -> u32 { + self.0 + } +} + +struct VfsFileData { + root: VfsRoot, + path: RelativePathBuf, + text: Arc, +} + +#[derive(Default)] +struct Vfs { + roots: Arena, + files: Arena, + // pending_changes: Vec, +} + +impl Vfs { + pub fn new(mut roots: Vec) -> Vfs { + let mut res = Vfs::default(); + + roots.sort_by_key(|it| Reverse(it.as_os_str().len())); + + for path in roots { + res.roots.alloc(RootFilter::new(path)); + } + res + } + + pub fn add_file_overlay(&mut self, path: &Path, content: String) {} + + pub fn change_file_overlay(&mut self, path: &Path, new_content: String) {} + + pub fn remove_file_overlay(&mut self, path: &Path) {} + + pub fn commit_changes(&mut self) -> Vec { + unimplemented!() + } +} + +#[derive(Debug, Clone)] +pub enum VfsChange { + AddRoot { + root: VfsRoot, + files: Vec<(VfsFile, RelativePathBuf, Arc)>, + }, + AddFile { + file: VfsFile, + root: VfsRoot, + path: RelativePathBuf, + text: Arc, + }, + RemoveFile { + file: VfsFile, + }, + ChangeFile { + file: VfsFile, + text: Arc, + }, +} -- cgit v1.2.3 From 2ae05a6163d8b15f3d8a18a2ab713d1fbd83c505 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Dec 2018 13:18:55 +0300 Subject: vfs crate scaffold --- Cargo.lock | 2 + crates/ra_lsp_server/src/main_loop.rs | 4 +- crates/ra_vfs/Cargo.toml | 3 + crates/ra_vfs/src/io.rs | 117 +++++++++++++++++----------------- crates/ra_vfs/src/lib.rs | 25 +++++++- crates/thread_worker/src/lib.rs | 6 +- 6 files changed, 89 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 38307ff69..c15955f4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -749,8 +749,10 @@ name = "ra_vfs" version = "0.1.0" dependencies = [ "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_worker 0.1.0", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index eab82ee85..9d3f83b4c 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -88,8 +88,8 @@ pub fn main_loop( drop(pool); log::info!("...threadpool has finished"); - let fs_res = fs_watcher.stop(); - let ws_res = ws_watcher.stop(); + let fs_res = fs_watcher.shutdown(); + let ws_res = ws_watcher.shutdown(); main_res?; fs_res.map_err(|_| format_err!("fs watcher died"))?; diff --git a/crates/ra_vfs/Cargo.toml b/crates/ra_vfs/Cargo.toml index f8d49b3f5..9ce619a77 100644 --- a/crates/ra_vfs/Cargo.toml +++ b/crates/ra_vfs/Cargo.toml @@ -9,3 +9,6 @@ walkdir = "2.2.7" relative-path = "0.4.0" rustc-hash = "1.0" crossbeam-channel = "0.2.4" +log = "0.4.6" + +thread_worker = { path = "../thread_worker" } diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs index f90fe0e84..ce3271d48 100644 --- a/crates/ra_vfs/src/io.rs +++ b/crates/ra_vfs/src/io.rs @@ -6,67 +6,64 @@ use std::{ use walkdir::WalkDir; use crossbeam_channel::{Sender, Receiver}; +use thread_worker::{WorkerHandle, Worker}; -pub(crate) fn start_io() -> (JoinHandle<(), Sender<()>, Receiver()>) {} +#[derive(Debug)] +pub struct FileEvent { + pub path: PathBuf, + pub kind: FileEventKind, +} -// use crate::thread_watcher::{ThreadWatcher, Worker}; +#[derive(Debug)] +pub enum FileEventKind { + Add(String), +} -// #[derive(Debug)] -// pub struct FileEvent { -// pub path: PathBuf, -// pub kind: FileEventKind, -// } +pub fn start() -> (Worker)>, WorkerHandle) { + thread_worker::spawn::), _>( + "vfs", + 128, + |input_receiver, output_sender| { + input_receiver + .map(|path| { + log::debug!("loading {} ...", path.as_path().display()); + let events = load_root(path.as_path()); + log::debug!("... loaded {}", path.as_path().display()); + (path, events) + }) + .for_each(|it| output_sender.send(it)) + }, + ) +} -// #[derive(Debug)] -// pub enum FileEventKind { -// Add(String), -// } - -// pub fn roots_loader() -> (Worker)>, ThreadWatcher) { -// Worker::)>::spawn( -// "roots loader", -// 128, -// |input_receiver, output_sender| { -// input_receiver -// .map(|path| { -// log::debug!("loading {} ...", path.as_path().display()); -// let events = load_root(path.as_path()); -// log::debug!("... loaded {}", path.as_path().display()); -// (path, events) -// }) -// .for_each(|it| output_sender.send(it)) -// }, -// ) -// } - -// fn load_root(path: &Path) -> Vec { -// let mut res = Vec::new(); -// for entry in WalkDir::new(path) { -// let entry = match entry { -// Ok(entry) => entry, -// Err(e) => { -// log::warn!("watcher error: {}", e); -// continue; -// } -// }; -// if !entry.file_type().is_file() { -// continue; -// } -// let path = entry.path(); -// if path.extension().and_then(|os| os.to_str()) != Some("rs") { -// continue; -// } -// let text = match fs::read_to_string(path) { -// Ok(text) => text, -// Err(e) => { -// log::warn!("watcher error: {}", e); -// continue; -// } -// }; -// res.push(FileEvent { -// path: path.to_owned(), -// kind: FileEventKind::Add(text), -// }) -// } -// res -// } +fn load_root(path: &Path) -> Vec { + let mut res = Vec::new(); + for entry in WalkDir::new(path) { + let entry = match entry { + Ok(entry) => entry, + Err(e) => { + log::warn!("watcher error: {}", e); + continue; + } + }; + if !entry.file_type().is_file() { + continue; + } + let path = entry.path(); + if path.extension().and_then(|os| os.to_str()) != Some("rs") { + continue; + } + let text = match fs::read_to_string(path) { + Ok(text) => text, + Err(e) => { + log::warn!("watcher error: {}", e); + continue; + } + }; + res.push(FileEvent { + path: path.to_owned(), + kind: FileEventKind::Add(text), + }) + } + res +} diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 8f6abadb7..b80c12058 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -15,6 +15,7 @@ mod arena; mod io; use std::{ + thread, cmp::Reverse, path::{Path, PathBuf}, ffi::OsStr, @@ -22,7 +23,12 @@ use std::{ }; use relative_path::RelativePathBuf; -use crate::arena::{ArenaId, Arena}; +use thread_worker::{WorkerHandle, Worker}; + +use crate::{ + arena::{ArenaId, Arena}, + io::FileEvent, +}; /// `RootFilter` is a predicate that checks if a file can belong to a root struct RootFilter { @@ -76,16 +82,24 @@ struct VfsFileData { text: Arc, } -#[derive(Default)] struct Vfs { roots: Arena, files: Arena, // pending_changes: Vec, + worker: Worker)>, + worker_handle: WorkerHandle, } impl Vfs { pub fn new(mut roots: Vec) -> Vfs { - let mut res = Vfs::default(); + let (worker, worker_handle) = io::start(); + + let mut res = Vfs { + roots: Arena::default(), + files: Arena::default(), + worker, + worker_handle, + }; roots.sort_by_key(|it| Reverse(it.as_os_str().len())); @@ -104,6 +118,11 @@ impl Vfs { pub fn commit_changes(&mut self) -> Vec { unimplemented!() } + + pub fn shutdown(self) -> thread::Result<()> { + let _ = self.worker.shutdown(); + self.worker_handle.shutdown() + } } #[derive(Debug, Clone)] diff --git a/crates/thread_worker/src/lib.rs b/crates/thread_worker/src/lib.rs index e558559ef..24d7fcce1 100644 --- a/crates/thread_worker/src/lib.rs +++ b/crates/thread_worker/src/lib.rs @@ -30,7 +30,7 @@ where impl Worker { /// Stops the worker. Returns the message receiver to fetch results which /// have become ready before the worker is stopped. - pub fn stop(self) -> Receiver { + pub fn shutdown(self) -> Receiver { self.out } @@ -45,11 +45,11 @@ impl WorkerHandle { WorkerHandle { name, thread, - bomb: DropBomb::new(format!("WorkerHandle {} was not stopped", name)), + bomb: DropBomb::new(format!("WorkerHandle {} was not shutdown", name)), } } - pub fn stop(mut self) -> thread::Result<()> { + pub fn shutdown(mut self) -> thread::Result<()> { log::info!("waiting for {} to finish ...", self.name); let name = self.name; self.bomb.defuse(); -- cgit v1.2.3 From 99561cf2f20ad572c7149644a70cd7740c0f8b86 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Dec 2018 13:23:23 +0300 Subject: Add type alias --- crates/ra_vfs/src/io.rs | 4 +++- crates/ra_vfs/src/lib.rs | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs index ce3271d48..257f1bf53 100644 --- a/crates/ra_vfs/src/io.rs +++ b/crates/ra_vfs/src/io.rs @@ -19,7 +19,9 @@ pub enum FileEventKind { Add(String), } -pub fn start() -> (Worker)>, WorkerHandle) { +pub(crate) type FsWorker = Worker)>; + +pub(crate) fn start() -> (FsWorker, WorkerHandle) { thread_worker::spawn::), _>( "vfs", 128, diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index b80c12058..d4ba2cb45 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -27,10 +27,11 @@ use thread_worker::{WorkerHandle, Worker}; use crate::{ arena::{ArenaId, Arena}, - io::FileEvent, + io::{FileEvent, FsWorker}, }; -/// `RootFilter` is a predicate that checks if a file can belong to a root +/// `RootFilter` is a predicate that checks if a file can belong to a root. If +/// several filters match a file (nested dirs), the most nested one wins. struct RootFilter { root: PathBuf, file_filter: fn(&Path) -> bool, @@ -86,7 +87,7 @@ struct Vfs { roots: Arena, files: Arena, // pending_changes: Vec, - worker: Worker)>, + worker: FsWorker, worker_handle: WorkerHandle, } @@ -101,6 +102,7 @@ impl Vfs { worker_handle, }; + // A hack to make nesting work. roots.sort_by_key(|it| Reverse(it.as_os_str().len())); for path in roots { -- cgit v1.2.3 From e69b05781f7fb0f0dfdcd4acb433dbcde9cbb7b7 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Dec 2018 13:35:05 +0300 Subject: add io::Task --- crates/ra_vfs/src/io.rs | 53 ++++++++++++++++++++++++++++-------------------- crates/ra_vfs/src/lib.rs | 7 +++---- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs index 257f1bf53..c46760583 100644 --- a/crates/ra_vfs/src/io.rs +++ b/crates/ra_vfs/src/io.rs @@ -4,38 +4,47 @@ use std::{ thread::JoinHandle, }; -use walkdir::WalkDir; +use walkdir::{DirEntry, WalkDir}; use crossbeam_channel::{Sender, Receiver}; -use thread_worker::{WorkerHandle, Worker}; +use thread_worker::{WorkerHandle}; + +use crate::VfsRoot; + +pub(crate) enum Task { + ScanRoot { + root: VfsRoot, + path: PathBuf, + filter: Box bool + Send>, + }, +} #[derive(Debug)] -pub struct FileEvent { - pub path: PathBuf, - pub kind: FileEventKind, +pub(crate) struct FileEvent { + pub(crate) path: PathBuf, + pub(crate) kind: FileEventKind, } #[derive(Debug)] -pub enum FileEventKind { +pub(crate) enum FileEventKind { Add(String), } -pub(crate) type FsWorker = Worker)>; +pub(crate) type Worker = thread_worker::Worker)>; + +pub(crate) fn start() -> (Worker, WorkerHandle) { + thread_worker::spawn("vfs", 128, |input_receiver, output_sender| { + input_receiver + .map(handle_task) + .for_each(|it| output_sender.send(it)) + }) +} -pub(crate) fn start() -> (FsWorker, WorkerHandle) { - thread_worker::spawn::), _>( - "vfs", - 128, - |input_receiver, output_sender| { - input_receiver - .map(|path| { - log::debug!("loading {} ...", path.as_path().display()); - let events = load_root(path.as_path()); - log::debug!("... loaded {}", path.as_path().display()); - (path, events) - }) - .for_each(|it| output_sender.send(it)) - }, - ) +fn handle_task(task: Task) -> (PathBuf, Vec) { + let Task::ScanRoot { path, .. } = task; + log::debug!("loading {} ...", path.as_path().display()); + let events = load_root(path.as_path()); + log::debug!("... loaded {}", path.as_path().display()); + (path, events) } fn load_root(path: &Path) -> Vec { diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index d4ba2cb45..8ce6b6ee0 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -2,8 +2,8 @@ //! //! When doing analysis, we don't want to do any IO, we want to keep all source //! code in memory. However, the actual source code is stored on disk, so you -//! need to get it into the memory in the first place somehow. VFS is the //! component which does this. +//! need to get it into the memory in the first place somehow. VFS is the //! //! It also is responsible for watching the disk for changes, and for merging //! editor state (modified, unsaved files) with disk state. @@ -23,11 +23,10 @@ use std::{ }; use relative_path::RelativePathBuf; -use thread_worker::{WorkerHandle, Worker}; +use thread_worker::{WorkerHandle}; use crate::{ arena::{ArenaId, Arena}, - io::{FileEvent, FsWorker}, }; /// `RootFilter` is a predicate that checks if a file can belong to a root. If @@ -87,7 +86,7 @@ struct Vfs { roots: Arena, files: Arena, // pending_changes: Vec, - worker: FsWorker, + worker: io::Worker, worker_handle: WorkerHandle, } -- cgit v1.2.3 From a422d480a188a28c6b5e7862fbf07817eb2c7447 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Dec 2018 16:38:05 +0300 Subject: implement vfs events handling --- Cargo.lock | 81 ++++++++++++ crates/ra_lsp_server/tests/heavy_tests/support.rs | 4 +- crates/ra_vfs/Cargo.toml | 3 + crates/ra_vfs/src/arena.rs | 7 +- crates/ra_vfs/src/io.rs | 43 +++--- crates/ra_vfs/src/lib.rs | 153 ++++++++++++++++++++-- crates/ra_vfs/tests/vfs.rs | 101 ++++++++++++++ 7 files changed, 349 insertions(+), 43 deletions(-) create mode 100644 crates/ra_vfs/tests/vfs.rs diff --git a/Cargo.lock b/Cargo.lock index c15955f4c..aac4d91b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -752,6 +752,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "thread_worker 0.1.0", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -778,6 +779,33 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_chacha" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_core" version = "0.2.2" @@ -791,6 +819,39 @@ name = "rand_core" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_pcg" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rayon" version = "1.0.3" @@ -1068,6 +1129,19 @@ dependencies = [ "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tempfile" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tera" version = "0.11.20" @@ -1431,8 +1505,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" +"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a" +"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" "checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" "checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" +"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" +"checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3" "checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" "checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" "checksum redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bcd297b87a545980a2d25a0beb72a1f490c31f0a9fde52fca35bfbb1ceb70" @@ -1467,6 +1547,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9545a6a093a3f0bd59adb472700acc08cad3776f860f16a897dfce8c88721cbc" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +"checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2" "checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3" "checksum teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d89ad4617d1dec55331067fadaa041e813479e1779616f3d3ce9308bf46184e" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index 07a878a26..c14d287ca 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs @@ -174,11 +174,11 @@ impl Server { impl Drop for Server { fn drop(&mut self) { self.send_request::(666, ()); - let receiver = self.worker.take().unwrap().stop(); + let receiver = self.worker.take().unwrap().shutdown(); while let Some(msg) = recv_timeout(&receiver) { drop(msg); } - self.watcher.take().unwrap().stop().unwrap(); + self.watcher.take().unwrap().shutdown().unwrap(); } } diff --git a/crates/ra_vfs/Cargo.toml b/crates/ra_vfs/Cargo.toml index 9ce619a77..ccea8a866 100644 --- a/crates/ra_vfs/Cargo.toml +++ b/crates/ra_vfs/Cargo.toml @@ -12,3 +12,6 @@ crossbeam-channel = "0.2.4" log = "0.4.6" thread_worker = { path = "../thread_worker" } + +[dev-dependencies] +tempfile = "3" diff --git a/crates/ra_vfs/src/arena.rs b/crates/ra_vfs/src/arena.rs index d6fad753b..6b42ae26d 100644 --- a/crates/ra_vfs/src/arena.rs +++ b/crates/ra_vfs/src/arena.rs @@ -1,5 +1,4 @@ use std::{ - hash::{Hash, Hasher}, marker::PhantomData, ops::{Index, IndexMut}, }; @@ -21,6 +20,12 @@ impl Arena { self.data.push(value); ID::from_u32(id) } + pub fn iter<'a>(&'a self) -> impl Iterator { + self.data + .iter() + .enumerate() + .map(|(idx, value)| (ID::from_u32(idx as u32), value)) + } } impl Default for Arena { diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs index c46760583..178c9beff 100644 --- a/crates/ra_vfs/src/io.rs +++ b/crates/ra_vfs/src/io.rs @@ -1,35 +1,26 @@ use std::{ fs, path::{Path, PathBuf}, - thread::JoinHandle, }; use walkdir::{DirEntry, WalkDir}; -use crossbeam_channel::{Sender, Receiver}; use thread_worker::{WorkerHandle}; +use relative_path::RelativePathBuf; use crate::VfsRoot; -pub(crate) enum Task { - ScanRoot { - root: VfsRoot, - path: PathBuf, - filter: Box bool + Send>, - }, -} - -#[derive(Debug)] -pub(crate) struct FileEvent { +pub(crate) struct Task { + pub(crate) root: VfsRoot, pub(crate) path: PathBuf, - pub(crate) kind: FileEventKind, + pub(crate) filter: Box bool + Send>, } -#[derive(Debug)] -pub(crate) enum FileEventKind { - Add(String), +pub struct TaskResult { + pub(crate) root: VfsRoot, + pub(crate) files: Vec<(RelativePathBuf, String)>, } -pub(crate) type Worker = thread_worker::Worker)>; +pub(crate) type Worker = thread_worker::Worker; pub(crate) fn start() -> (Worker, WorkerHandle) { thread_worker::spawn("vfs", 128, |input_receiver, output_sender| { @@ -39,17 +30,17 @@ pub(crate) fn start() -> (Worker, WorkerHandle) { }) } -fn handle_task(task: Task) -> (PathBuf, Vec) { - let Task::ScanRoot { path, .. } = task; +fn handle_task(task: Task) -> TaskResult { + let Task { root, path, filter } = task; log::debug!("loading {} ...", path.as_path().display()); - let events = load_root(path.as_path()); + let files = load_root(path.as_path(), &*filter); log::debug!("... loaded {}", path.as_path().display()); - (path, events) + TaskResult { root, files } } -fn load_root(path: &Path) -> Vec { +fn load_root(root: &Path, filter: &dyn Fn(&DirEntry) -> bool) -> Vec<(RelativePathBuf, String)> { let mut res = Vec::new(); - for entry in WalkDir::new(path) { + for entry in WalkDir::new(root).into_iter().filter_entry(filter) { let entry = match entry { Ok(entry) => entry, Err(e) => { @@ -71,10 +62,8 @@ fn load_root(path: &Path) -> Vec { continue; } }; - res.push(FileEvent { - path: path.to_owned(), - kind: FileEventKind::Add(text), - }) + let path = RelativePathBuf::from_path(path.strip_prefix(root).unwrap()).unwrap(); + res.push((path.to_owned(), text)) } res } diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 8ce6b6ee0..792f722a7 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -15,14 +15,19 @@ mod arena; mod io; use std::{ + mem, thread, cmp::Reverse, path::{Path, PathBuf}, ffi::OsStr, sync::Arc, + fs, }; +use rustc_hash::{FxHashMap, FxHashSet}; use relative_path::RelativePathBuf; +use crossbeam_channel::Receiver; +use walkdir::DirEntry; use thread_worker::{WorkerHandle}; use crate::{ @@ -40,15 +45,25 @@ impl RootFilter { fn new(root: PathBuf) -> RootFilter { RootFilter { root, - file_filter: rs_extension_filter, + file_filter: has_rs_extension, } } - fn can_contain(&self, path: &Path) -> bool { - (self.file_filter)(path) && path.starts_with(&self.root) + /// Check if this root can contain `path`. NB: even if this returns + /// true, the `path` might actually be conained in some nested root. + fn can_contain(&self, path: &Path) -> Option { + if !(self.file_filter)(path) { + return None; + } + if !(path.starts_with(&self.root)) { + return None; + } + let path = path.strip_prefix(&self.root).unwrap(); + let path = RelativePathBuf::from_path(path).unwrap(); + Some(path) } } -fn rs_extension_filter(p: &Path) -> bool { +fn has_rs_extension(p: &Path) -> bool { p.extension() == Some(OsStr::new("rs")) } @@ -82,10 +97,11 @@ struct VfsFileData { text: Arc, } -struct Vfs { +pub struct Vfs { roots: Arena, files: Arena, - // pending_changes: Vec, + root2files: FxHashMap>, + pending_changes: Vec, worker: io::Worker, worker_handle: WorkerHandle, } @@ -97,33 +113,144 @@ impl Vfs { let mut res = Vfs { roots: Arena::default(), files: Arena::default(), + root2files: FxHashMap::default(), worker, worker_handle, + pending_changes: Vec::new(), }; // A hack to make nesting work. roots.sort_by_key(|it| Reverse(it.as_os_str().len())); - - for path in roots { - res.roots.alloc(RootFilter::new(path)); + for (i, path) in roots.iter().enumerate() { + let root = res.roots.alloc(RootFilter::new(path.clone())); + let nested = roots[..i] + .iter() + .filter(|it| it.starts_with(path)) + .map(|it| it.clone()) + .collect::>(); + let filter = move |entry: &DirEntry| { + if entry.file_type().is_file() { + has_rs_extension(entry.path()) + } else { + nested.iter().all(|it| it != entry.path()) + } + }; + let task = io::Task { + root, + path: path.clone(), + filter: Box::new(filter), + }; + res.worker.inp.send(task); } res } - pub fn add_file_overlay(&mut self, path: &Path, content: String) {} + pub fn task_receiver(&self) -> &Receiver { + &self.worker.out + } + + pub fn handle_task(&mut self, task: io::TaskResult) { + let mut files = Vec::new(); + for (path, text) in task.files { + let text = Arc::new(text); + let file = self.add_file(task.root, path.clone(), Arc::clone(&text)); + files.push((file, path, text)); + } + let change = VfsChange::AddRoot { + root: task.root, + files, + }; + self.pending_changes.push(change); + } - pub fn change_file_overlay(&mut self, path: &Path, new_content: String) {} + pub fn add_file_overlay(&mut self, path: &Path, text: String) { + if let Some((root, path, file)) = self.find_root(path) { + let text = Arc::new(text); + let change = if let Some(file) = file { + self.change_file(file, Arc::clone(&text)); + VfsChange::ChangeFile { file, text } + } else { + let file = self.add_file(root, path.clone(), Arc::clone(&text)); + VfsChange::AddFile { + file, + text, + root, + path, + } + }; + self.pending_changes.push(change); + } + } - pub fn remove_file_overlay(&mut self, path: &Path) {} + pub fn change_file_overlay(&mut self, path: &Path, new_text: String) { + if let Some((_root, _path, file)) = self.find_root(path) { + let file = file.expect("can't change a file which wasn't added"); + let text = Arc::new(new_text); + self.change_file(file, Arc::clone(&text)); + let change = VfsChange::ChangeFile { file, text }; + self.pending_changes.push(change); + } + } + + pub fn remove_file_overlay(&mut self, path: &Path) { + if let Some((root, path, file)) = self.find_root(path) { + let file = file.expect("can't remove a file which wasn't added"); + let full_path = path.to_path(&self.roots[root].root); + let change = if let Ok(text) = fs::read_to_string(&full_path) { + let text = Arc::new(text); + self.change_file(file, Arc::clone(&text)); + VfsChange::ChangeFile { file, text } + } else { + self.remove_file(file); + VfsChange::RemoveFile { file } + }; + self.pending_changes.push(change); + } + } pub fn commit_changes(&mut self) -> Vec { - unimplemented!() + mem::replace(&mut self.pending_changes, Vec::new()) } pub fn shutdown(self) -> thread::Result<()> { let _ = self.worker.shutdown(); self.worker_handle.shutdown() } + + fn add_file(&mut self, root: VfsRoot, path: RelativePathBuf, text: Arc) -> VfsFile { + let data = VfsFileData { root, path, text }; + let file = self.files.alloc(data); + self.root2files + .entry(root) + .or_insert_with(FxHashSet::default) + .insert(file); + file + } + + fn change_file(&mut self, file: VfsFile, new_text: Arc) { + self.files[file].text = new_text; + } + + fn remove_file(&mut self, file: VfsFile) { + //FIXME: use arena with removal + self.files[file].text = Default::default(); + self.files[file].path = Default::default(); + let root = self.files[file].root; + let removed = self.root2files.get_mut(&root).unwrap().remove(&file); + assert!(removed); + } + + fn find_root(&self, path: &Path) -> Option<(VfsRoot, RelativePathBuf, Option)> { + let (root, path) = self + .roots + .iter() + .find_map(|(root, data)| data.can_contain(path).map(|it| (root, it)))?; + let file = self.root2files[&root] + .iter() + .map(|&it| it) + .find(|&file| self.files[file].path == path); + Some((root, path, file)) + } } #[derive(Debug, Clone)] diff --git a/crates/ra_vfs/tests/vfs.rs b/crates/ra_vfs/tests/vfs.rs new file mode 100644 index 000000000..4f44215c8 --- /dev/null +++ b/crates/ra_vfs/tests/vfs.rs @@ -0,0 +1,101 @@ +use std::{ + fs, + collections::HashSet, +}; + +use tempfile::tempdir; + +use ra_vfs::{Vfs, VfsChange}; + +#[test] +fn test_vfs_works() -> std::io::Result<()> { + let files = [ + ("a/foo.rs", "hello"), + ("a/bar.rs", "world"), + ("a/b/baz.rs", "nested hello"), + ]; + + let dir = tempdir()?; + for (path, text) in files.iter() { + let file_path = dir.path().join(path); + fs::create_dir_all(file_path.parent().unwrap())?; + fs::write(file_path, text)? + } + + let a_root = dir.path().join("a"); + let b_root = dir.path().join("a/b"); + + let mut vfs = Vfs::new(vec![a_root, b_root]); + for _ in 0..2 { + let task = vfs.task_receiver().recv().unwrap(); + vfs.handle_task(task); + } + { + let files = vfs + .commit_changes() + .into_iter() + .flat_map(|change| { + let files = match change { + VfsChange::AddRoot { files, .. } => files, + _ => panic!("unexpected change"), + }; + files.into_iter().map(|(_id, path, text)| { + let text: String = (&*text).clone(); + (format!("{}", path.display()), text) + }) + }) + .collect::>(); + + let expected_files = [ + ("foo.rs", "hello"), + ("bar.rs", "world"), + ("baz.rs", "nested hello"), + ] + .iter() + .map(|(path, text)| (path.to_string(), text.to_string())) + .collect::>(); + + assert_eq!(files, expected_files); + } + + vfs.add_file_overlay(&dir.path().join("a/b/baz.rs"), "quux".to_string()); + let change = vfs.commit_changes().pop().unwrap(); + match change { + VfsChange::ChangeFile { text, .. } => assert_eq!(&*text, "quux"), + _ => panic!("unexpected change"), + } + + vfs.change_file_overlay(&dir.path().join("a/b/baz.rs"), "m".to_string()); + let change = vfs.commit_changes().pop().unwrap(); + match change { + VfsChange::ChangeFile { text, .. } => assert_eq!(&*text, "m"), + _ => panic!("unexpected change"), + } + + vfs.remove_file_overlay(&dir.path().join("a/b/baz.rs")); + let change = vfs.commit_changes().pop().unwrap(); + match change { + VfsChange::ChangeFile { text, .. } => assert_eq!(&*text, "nested hello"), + _ => panic!("unexpected change"), + } + + vfs.add_file_overlay(&dir.path().join("a/b/spam.rs"), "spam".to_string()); + let change = vfs.commit_changes().pop().unwrap(); + match change { + VfsChange::AddFile { text, path, .. } => { + assert_eq!(&*text, "spam"); + assert_eq!(path, "spam.rs"); + } + _ => panic!("unexpected change"), + } + + vfs.remove_file_overlay(&dir.path().join("a/b/spam.rs")); + let change = vfs.commit_changes().pop().unwrap(); + match change { + VfsChange::RemoveFile { .. } => (), + _ => panic!("unexpected change"), + } + + vfs.shutdown().unwrap(); + Ok(()) +} -- cgit v1.2.3 From cb6205c09da9fd6fc0bd9f88106f5e9bd3f471aa Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Dec 2018 17:22:48 +0300 Subject: use relpaths for module resolve --- Cargo.lock | 1 + crates/ra_db/src/input.rs | 14 ++++++++++++++ crates/ra_hir/Cargo.toml | 1 + crates/ra_hir/src/module/imp.rs | 37 +++++++++++++++++++------------------ 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aac4d91b3..0a7128d0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -674,6 +674,7 @@ dependencies = [ name = "ra_hir" version = "0.1.0" dependencies = [ + "arrayvec 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "id-arena 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index ac144b991..b09014dc6 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use rustc_hash::{FxHashSet, FxHashMap}; +use relative_path::RelativePathBuf; use ra_syntax::SmolStr; use salsa; @@ -85,10 +86,23 @@ salsa::query_group! { type FileTextQuery; storage input; } + /// Path to a file, relative to the root of its source root. + fn file_relative_path(file_id: FileId) -> RelativePathBuf { + type FileRelativePathQuery; + storage input; + } fn file_source_root(file_id: FileId) -> SourceRootId { type FileSourceRootQuery; storage input; } + fn source_root_files(id: SourceRootId) -> Arc> { + type SourceRootFilesQuery; + storage input; + } + fn source_root_file_by_path(id: SourceRootId, path: RelativePathBuf) -> Option { + type SourceRootFilesByPathQuery; + storage input; + } fn source_root(id: SourceRootId) -> Arc { type SourceRootQuery; storage input; diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index 1b9e148b2..61650cee9 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml @@ -5,6 +5,7 @@ version = "0.1.0" authors = ["Aleksey Kladov "] [dependencies] +arrayvec = "0.4.9" log = "0.4.5" relative-path = "0.4.0" salsa = "0.8.0" diff --git a/crates/ra_hir/src/module/imp.rs b/crates/ra_hir/src/module/imp.rs index 4a19842c4..d04d24a61 100644 --- a/crates/ra_hir/src/module/imp.rs +++ b/crates/ra_hir/src/module/imp.rs @@ -4,9 +4,9 @@ use ra_syntax::{ ast::{self, NameOwner}, SmolStr, }; -use relative_path::RelativePathBuf; use rustc_hash::{FxHashMap, FxHashSet}; -use ra_db::{SourceRoot, SourceRootId, FileResolverImp, Cancelable, FileId,}; +use arrayvec::ArrayVec; +use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; use crate::{ HirDatabase, @@ -110,8 +110,7 @@ fn build_subtree( let (points_to, problem) = match sub { Submodule::Declaration(name) => { - let (points_to, problem) = - resolve_submodule(source, &name, &source_root.file_resolver); + let (points_to, problem) = resolve_submodule(db, source, &name); let points_to = points_to .into_iter() .map(|file_id| match roots.remove(&file_id) { @@ -153,30 +152,32 @@ fn build_subtree( } fn resolve_submodule( + db: &impl HirDatabase, source: ModuleSource, name: &SmolStr, - file_resolver: &FileResolverImp, ) -> (Vec, Option) { - // TODO: handle submodules of inline modules properly + // FIXME: handle submodules of inline modules properly let file_id = source.file_id(); - let mod_name = file_resolver.file_stem(file_id); + let source_root_id = db.file_source_root(file_id); + let path = db.file_relative_path(file_id); + let dir_path = path.parent().unwrap(); + let mod_name = path.file_stem().unwrap_or("unknown"); let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; - let file_mod = RelativePathBuf::from(format!("../{}.rs", name)); - let dir_mod = RelativePathBuf::from(format!("../{}/mod.rs", name)); - let file_dir_mod = RelativePathBuf::from(format!("../{}/{}.rs", mod_name, name)); - let tmp1; - let tmp2; - let candidates = if is_dir_owner { - tmp1 = [&file_mod, &dir_mod]; - tmp1.iter() + let file_mod = dir_path.join(format!("{}.rs", name)); + let dir_mod = dir_path.join(format!("{}/mod.rs", name)); + let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name)); + let mut candidates = ArrayVec::<[_; 2]>::new(); + if is_dir_owner { + candidates.push(file_mod.clone()); + candidates.push(dir_mod); } else { - tmp2 = [&file_dir_mod]; - tmp2.iter() + candidates.push(file_dir_mod.clone()); }; let points_to = candidates - .filter_map(|path| file_resolver.resolve(file_id, path)) + .into_iter() + .filter_map(|path| db.source_root_file_by_path(source_root_id, path)) .collect::>(); let problem = if points_to.is_empty() { Some(Problem::UnresolvedModule { -- cgit v1.2.3 From dea1a69e1cb0af7d6917d351a811ef205b7dfef9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Dec 2018 17:23:49 +0300 Subject: remove relpath from input --- crates/ra_db/src/input.rs | 3 --- crates/ra_db/src/mock.rs | 10 ++-------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index b09014dc6..9edaf36cf 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs @@ -5,8 +5,6 @@ use relative_path::RelativePathBuf; use ra_syntax::SmolStr; use salsa; -use crate::file_resolver::FileResolverImp; - #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct FileId(pub u32); @@ -123,7 +121,6 @@ pub struct SourceRootId(pub u32); #[derive(Default, Clone, Debug, PartialEq, Eq)] pub struct SourceRoot { - pub file_resolver: FileResolverImp, pub files: FxHashSet, } diff --git a/crates/ra_db/src/mock.rs b/crates/ra_db/src/mock.rs index 2f7551597..14d9e79b5 100644 --- a/crates/ra_db/src/mock.rs +++ b/crates/ra_db/src/mock.rs @@ -1,9 +1,7 @@ -use std::sync::Arc; - use rustc_hash::FxHashSet; use relative_path::{RelativePath, RelativePathBuf}; -use crate::{FileId, FileResolver, SourceRoot, FileResolverImp}; +use crate::{FileId, FileResolver, SourceRoot}; #[derive(Default, Debug, Clone)] pub struct FileMap(Vec<(FileId, RelativePathBuf)>); @@ -17,11 +15,7 @@ impl FileMap { pub fn into_source_root(self) -> SourceRoot { let files = self.files(); - let file_resolver = FileResolverImp::new(Arc::new(self)); - SourceRoot { - file_resolver, - files, - } + SourceRoot { files } } pub fn files(&self) -> FxHashSet { -- cgit v1.2.3 From b6ce7a6d344fa673addcd299cbb19b050625e04d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 10:26:24 +0300 Subject: make it compile --- crates/ra_analysis/src/db.rs | 3 +++ crates/ra_analysis/src/imp.rs | 9 +-------- crates/ra_db/src/input.rs | 2 +- crates/ra_db/src/lib.rs | 1 + 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index b8d774eb5..9f39d3a59 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs @@ -61,7 +61,10 @@ salsa::database_storage! { pub(crate) struct RootDatabaseStorage for RootDatabase { impl ra_db::FilesDatabase { fn file_text() for ra_db::FileTextQuery; + fn file_relative_path() for ra_db::FileRelativePathQuery; fn file_source_root() for ra_db::FileSourceRootQuery; + fn source_root_files() for ra_db::SourceRootFilesQuery; + fn source_root_file_by_path() for ra_db::SourceRootFileByPathQuery; fn source_root() for ra_db::SourceRootQuery; fn libraries() for ra_db::LibrariesQuery; fn crate_graph() for ra_db::CrateGraphQuery; diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 0de0e2645..e2c20b0e3 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -51,9 +51,6 @@ impl AnalysisHostImpl { .set(file_id, Arc::new(text)) } if !(change.files_added.is_empty() && change.files_removed.is_empty()) { - let file_resolver = change - .file_resolver - .expect("change resolver when changing set of files"); let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); for (file_id, text) in change.files_added { self.db @@ -70,7 +67,6 @@ impl AnalysisHostImpl { .set(file_id, Arc::new(String::new())); source_root.files.remove(&file_id); } - source_root.file_resolver = file_resolver; self.db .query_mut(ra_db::SourceRootQuery) .set(WORKSPACE, Arc::new(source_root)) @@ -95,10 +91,7 @@ impl AnalysisHostImpl { .query_mut(ra_db::FileTextQuery) .set_constant(file_id, Arc::new(text)); } - let source_root = SourceRoot { - files, - file_resolver: library.file_resolver, - }; + let source_root = SourceRoot { files }; self.db .query_mut(ra_db::SourceRootQuery) .set(source_root_id, Arc::new(source_root)); diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 9edaf36cf..65b674da9 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs @@ -98,7 +98,7 @@ salsa::query_group! { storage input; } fn source_root_file_by_path(id: SourceRootId, path: RelativePathBuf) -> Option { - type SourceRootFilesByPathQuery; + type SourceRootFileByPathQuery; storage input; } fn source_root(id: SourceRootId) -> Arc { diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 53805aada..783b7a799 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -28,6 +28,7 @@ pub use crate::{ input::{ FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, WORKSPACE, FileTextQuery, FileSourceRootQuery, SourceRootQuery, LibrariesQuery, CrateGraphQuery, + FileRelativePathQuery, SourceRootFilesQuery, SourceRootFileByPathQuery, }, loc2id::{LocationIntener, NumericId}, }; -- cgit v1.2.3 From d0bab735c81d616629a54cca7b35c2f7cd26408a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 10:28:57 +0300 Subject: add root & path info to remove event --- crates/ra_vfs/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 792f722a7..20482c396 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -202,7 +202,7 @@ impl Vfs { VfsChange::ChangeFile { file, text } } else { self.remove_file(file); - VfsChange::RemoveFile { file } + VfsChange::RemoveFile { root, file, path } }; self.pending_changes.push(change); } @@ -260,13 +260,15 @@ pub enum VfsChange { files: Vec<(VfsFile, RelativePathBuf, Arc)>, }, AddFile { - file: VfsFile, root: VfsRoot, + file: VfsFile, path: RelativePathBuf, text: Arc, }, RemoveFile { + root: VfsRoot, file: VfsFile, + path: RelativePathBuf, }, ChangeFile { file: VfsFile, -- cgit v1.2.3 From 815a0e577821a3876aa4c79c13200607acadcd2f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 10:29:48 +0300 Subject: doc comment --- crates/ra_vfs/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 20482c396..6c1af5ef9 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -212,6 +212,7 @@ impl Vfs { mem::replace(&mut self.pending_changes, Vec::new()) } + /// Sutdown the VFS and terminate the background watching thread. pub fn shutdown(self) -> thread::Result<()> { let _ = self.worker.shutdown(); self.worker_handle.shutdown() -- cgit v1.2.3 From 85290bc1342560d5560f0b2151cff1c0c6dac155 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 12:20:54 +0300 Subject: switch analysis to vfs --- crates/ra_analysis/src/db.rs | 2 - crates/ra_analysis/src/imp.rs | 88 +++++++++++++++--------------- crates/ra_analysis/src/lib.rs | 96 +++++++++++++++++++++++++-------- crates/ra_analysis/src/mock_analysis.rs | 8 +-- crates/ra_db/src/input.rs | 22 +++----- crates/ra_db/src/lib.rs | 2 +- crates/ra_db/src/mock.rs | 7 +-- crates/ra_hir/src/module/imp.rs | 17 ++++-- 8 files changed, 142 insertions(+), 100 deletions(-) diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index 9f39d3a59..b79baf037 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs @@ -63,8 +63,6 @@ salsa::database_storage! { fn file_text() for ra_db::FileTextQuery; fn file_relative_path() for ra_db::FileRelativePathQuery; fn file_source_root() for ra_db::FileSourceRootQuery; - fn source_root_files() for ra_db::SourceRootFilesQuery; - fn source_root_file_by_path() for ra_db::SourceRootFileByPathQuery; fn source_root() for ra_db::SourceRootQuery; fn libraries() for ra_db::LibrariesQuery; fn crate_graph() for ra_db::CrateGraphQuery; diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index e2c20b0e3..51bcd5a73 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -12,7 +12,6 @@ use ra_syntax::{ }; use ra_db::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE, SyntaxDatabase}; use rayon::prelude::*; -use rustc_hash::FxHashSet; use salsa::{Database, ParallelDatabase}; use hir::{ self, @@ -25,7 +24,7 @@ use crate::{ completion::{completions, CompletionItem}, db, symbol_index::{SymbolIndex, SymbolsDatabase}, - AnalysisChange, Cancelable, CrateId, Diagnostic, FileId, + AnalysisChange, RootChange, Cancelable, CrateId, Diagnostic, FileId, FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit, ReferenceResolution, }; @@ -45,59 +44,22 @@ impl AnalysisHostImpl { log::info!("apply_change {:?}", change); // self.gc_syntax_trees(); + for (root_id, root_change) in change.roots_changed { + self.apply_root_change(root_id, root_change); + } for (file_id, text) in change.files_changed { self.db .query_mut(ra_db::FileTextQuery) .set(file_id, Arc::new(text)) } - if !(change.files_added.is_empty() && change.files_removed.is_empty()) { - let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); - for (file_id, text) in change.files_added { - self.db - .query_mut(ra_db::FileTextQuery) - .set(file_id, Arc::new(text)); - self.db - .query_mut(ra_db::FileSourceRootQuery) - .set(file_id, ra_db::WORKSPACE); - source_root.files.insert(file_id); - } - for file_id in change.files_removed { - self.db - .query_mut(ra_db::FileTextQuery) - .set(file_id, Arc::new(String::new())); - source_root.files.remove(&file_id); - } - self.db - .query_mut(ra_db::SourceRootQuery) - .set(WORKSPACE, Arc::new(source_root)) - } if !change.libraries_added.is_empty() { let mut libraries = Vec::clone(&self.db.libraries()); for library in change.libraries_added { - let source_root_id = SourceRootId(1 + libraries.len() as u32); - libraries.push(source_root_id); - let mut files = FxHashSet::default(); - for (file_id, text) in library.files { - files.insert(file_id); - log::debug!( - "library file: {:?} {:?}", - file_id, - library.file_resolver.debug_path(file_id) - ); - self.db - .query_mut(ra_db::FileSourceRootQuery) - .set_constant(file_id, source_root_id); - self.db - .query_mut(ra_db::FileTextQuery) - .set_constant(file_id, Arc::new(text)); - } - let source_root = SourceRoot { files }; + libraries.push(library.root_id); self.db .query_mut(ra_db::SourceRootQuery) - .set(source_root_id, Arc::new(source_root)); - self.db - .query_mut(crate::symbol_index::LibrarySymbolsQuery) - .set(source_root_id, Arc::new(library.symbol_index)); + .set(library.root_id, Default::default()); + self.apply_root_change(library.root_id, library.root_change); } self.db .query_mut(ra_db::LibrariesQuery) @@ -110,6 +72,34 @@ impl AnalysisHostImpl { } } + fn apply_root_change(&mut self, root_id: SourceRootId, root_change: RootChange) { + let mut source_root = SourceRoot::clone(&self.db.source_root(root_id)); + for add_file in root_change.added { + self.db + .query_mut(ra_db::FileTextQuery) + .set(add_file.file_id, add_file.text); + self.db + .query_mut(ra_db::FileRelativePathQuery) + .set(add_file.file_id, add_file.path.clone()); + self.db + .query_mut(ra_db::FileSourceRootQuery) + .set(add_file.file_id, root_id); + source_root.files.insert(add_file.path, add_file.file_id); + } + for remove_file in root_change.removed { + self.db + .query_mut(ra_db::FileTextQuery) + .set(remove_file.file_id, Default::default()); + self.db + .query_mut(ra_db::FileRelativePathQuery) + .set(remove_file.file_id, Default::default()); + source_root.files.remove(&remove_file.path); + } + self.db + .query_mut(ra_db::SourceRootQuery) + .set(root_id, Arc::new(source_root)); + } + #[allow(unused)] /// Ideally, we should call this function from time to time to collect heavy /// syntax trees. However, if we actually do that, everything is recomputed @@ -156,7 +146,13 @@ impl AnalysisImpl { .map(|&lib_id| self.db.library_symbols(lib_id)) .collect() } else { - let files = &self.db.source_root(WORKSPACE).files; + let files: Vec = self + .db + .source_root(WORKSPACE) + .files + .values() + .map(|&it| it) + .collect(); /// Need to wrap Snapshot to provide `Clone` impl for `map_with` struct Snap(salsa::Snapshot); diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 22fff71ab..bfc4e0f17 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -18,9 +18,9 @@ pub mod mock_analysis; use std::{fmt, sync::Arc}; +use rustc_hash::FxHashMap; use ra_syntax::{SourceFileNode, TextRange, TextUnit}; use ra_text_edit::AtomTextEdit; -use ra_db::FileResolverImp; use rayon::prelude::*; use relative_path::RelativePathBuf; @@ -39,28 +39,53 @@ pub use hir::FnSignatureInfo; pub use ra_db::{ Canceled, Cancelable, FilePosition, - CrateGraph, CrateId, FileId, FileResolver + CrateGraph, CrateId, SourceRootId, FileId, FileResolver, + WORKSPACE }; #[derive(Default)] pub struct AnalysisChange { - files_added: Vec<(FileId, String)>, + roots_changed: FxHashMap, files_changed: Vec<(FileId, String)>, - files_removed: Vec<(FileId)>, libraries_added: Vec, crate_graph: Option, - file_resolver: Option, +} + +#[derive(Default)] +struct RootChange { + added: Vec, + removed: Vec, +} + +#[derive(Debug)] +struct AddFile { + file_id: FileId, + path: RelativePathBuf, + text: Arc, +} + +#[derive(Debug)] +struct RemoveFile { + file_id: FileId, + path: RelativePathBuf, } impl fmt::Debug for AnalysisChange { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("AnalysisChange") - .field("files_added", &self.files_added.len()) + .field("roots_changed", &self.roots_changed) .field("files_changed", &self.files_changed.len()) - .field("files_removed", &self.files_removed.len()) .field("libraries_added", &self.libraries_added.len()) .field("crate_graph", &self.crate_graph) - .field("file_resolver", &self.file_resolver) + .finish() + } +} + +impl fmt::Debug for RootChange { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("AnalysisChange") + .field("added", &self.added.len()) + .field("removed", &self.removed.len()) .finish() } } @@ -69,14 +94,34 @@ impl AnalysisChange { pub fn new() -> AnalysisChange { AnalysisChange::default() } - pub fn add_file(&mut self, file_id: FileId, text: String) { - self.files_added.push((file_id, text)) + pub fn add_file( + &mut self, + root_id: SourceRootId, + file_id: FileId, + path: RelativePathBuf, + text: Arc, + ) { + let file = AddFile { + file_id, + path, + text, + }; + self.roots_changed + .entry(root_id) + .or_default() + .added + .push(file); } pub fn change_file(&mut self, file_id: FileId, new_text: String) { self.files_changed.push((file_id, new_text)) } - pub fn remove_file(&mut self, file_id: FileId) { - self.files_removed.push(file_id) + pub fn remove_file(&mut self, root_id: SourceRootId, file_id: FileId, path: RelativePathBuf) { + let file = RemoveFile { file_id, path }; + self.roots_changed + .entry(root_id) + .or_default() + .removed + .push(file); } pub fn add_library(&mut self, data: LibraryData) { self.libraries_added.push(data) @@ -84,9 +129,6 @@ impl AnalysisChange { pub fn set_crate_graph(&mut self, graph: CrateGraph) { self.crate_graph = Some(graph); } - pub fn set_file_resolver(&mut self, file_resolver: Arc) { - self.file_resolver = Some(FileResolverImp::new(file_resolver)); - } } /// `AnalysisHost` stores the current state of the world. @@ -313,20 +355,32 @@ impl Analysis { #[derive(Debug)] pub struct LibraryData { - files: Vec<(FileId, String)>, - file_resolver: FileResolverImp, + root_id: SourceRootId, + root_change: RootChange, symbol_index: SymbolIndex, } impl LibraryData { - pub fn prepare(files: Vec<(FileId, String)>, file_resolver: Arc) -> LibraryData { - let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, text)| { + pub fn prepare( + root_id: SourceRootId, + files: Vec<(FileId, RelativePathBuf, Arc)>, + ) -> LibraryData { + let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, _, text)| { let file = SourceFileNode::parse(text); (*file_id, file) })); + let mut root_change = RootChange::default(); + root_change.added = files + .into_iter() + .map(|(file_id, path, text)| AddFile { + file_id, + path, + text, + }) + .collect(); LibraryData { - files, - file_resolver: FileResolverImp::new(file_resolver), + root_id, + root_change, symbol_index, } } diff --git a/crates/ra_analysis/src/mock_analysis.rs b/crates/ra_analysis/src/mock_analysis.rs index 0d9a7a147..691af4a48 100644 --- a/crates/ra_analysis/src/mock_analysis.rs +++ b/crates/ra_analysis/src/mock_analysis.rs @@ -4,7 +4,7 @@ use relative_path::{RelativePathBuf}; use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; use ra_db::mock::FileMap; -use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FilePosition}; +use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FilePosition, WORKSPACE}; /// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis /// from a set of in-memory files. @@ -82,10 +82,10 @@ impl MockAnalysis { for (path, contents) in self.files.into_iter() { assert!(path.starts_with('/')); let path = RelativePathBuf::from_path(&path[1..]).unwrap(); - let file_id = file_map.add(path); - change.add_file(file_id, contents); + let file_id = file_map.add(path.clone()); + change.add_file(WORKSPACE, file_id, path, Arc::new(contents)); } - change.set_file_resolver(Arc::new(file_map)); + // change.set_file_resolver(Arc::new(file_map)); host.apply_change(change); host } diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 65b674da9..51daa8e86 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs @@ -1,10 +1,15 @@ use std::sync::Arc; -use rustc_hash::{FxHashSet, FxHashMap}; +use rustc_hash::{FxHashMap}; use relative_path::RelativePathBuf; use ra_syntax::SmolStr; use salsa; +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct SourceRootId(pub u32); + +pub const WORKSPACE: SourceRootId = SourceRootId(0); + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct FileId(pub u32); @@ -93,14 +98,6 @@ salsa::query_group! { type FileSourceRootQuery; storage input; } - fn source_root_files(id: SourceRootId) -> Arc> { - type SourceRootFilesQuery; - storage input; - } - fn source_root_file_by_path(id: SourceRootId, path: RelativePathBuf) -> Option { - type SourceRootFileByPathQuery; - storage input; - } fn source_root(id: SourceRootId) -> Arc { type SourceRootQuery; storage input; @@ -116,12 +113,7 @@ salsa::query_group! { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct SourceRootId(pub u32); - #[derive(Default, Clone, Debug, PartialEq, Eq)] pub struct SourceRoot { - pub files: FxHashSet, + pub files: FxHashMap, } - -pub const WORKSPACE: SourceRootId = SourceRootId(0); diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 783b7a799..d1db281e6 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -28,7 +28,7 @@ pub use crate::{ input::{ FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, WORKSPACE, FileTextQuery, FileSourceRootQuery, SourceRootQuery, LibrariesQuery, CrateGraphQuery, - FileRelativePathQuery, SourceRootFilesQuery, SourceRootFileByPathQuery, + FileRelativePathQuery }, loc2id::{LocationIntener, NumericId}, }; diff --git a/crates/ra_db/src/mock.rs b/crates/ra_db/src/mock.rs index 14d9e79b5..efe987bdd 100644 --- a/crates/ra_db/src/mock.rs +++ b/crates/ra_db/src/mock.rs @@ -1,7 +1,7 @@ use rustc_hash::FxHashSet; use relative_path::{RelativePath, RelativePathBuf}; -use crate::{FileId, FileResolver, SourceRoot}; +use crate::{FileId, FileResolver}; #[derive(Default, Debug, Clone)] pub struct FileMap(Vec<(FileId, RelativePathBuf)>); @@ -13,11 +13,6 @@ impl FileMap { file_id } - pub fn into_source_root(self) -> SourceRoot { - let files = self.files(); - SourceRoot { files } - } - pub fn files(&self) -> FxHashSet { self.iter().map(|(id, _)| id).collect() } diff --git a/crates/ra_hir/src/module/imp.rs b/crates/ra_hir/src/module/imp.rs index d04d24a61..f3a346152 100644 --- a/crates/ra_hir/src/module/imp.rs +++ b/crates/ra_hir/src/module/imp.rs @@ -4,6 +4,7 @@ use ra_syntax::{ ast::{self, NameOwner}, SmolStr, }; +use relative_path::{RelativePathBuf, RelativePath}; use rustc_hash::{FxHashMap, FxHashSet}; use arrayvec::ArrayVec; use ra_db::{SourceRoot, SourceRootId, Cancelable, FileId}; @@ -65,7 +66,7 @@ fn create_module_tree<'a>( let mut visited = FxHashSet::default(); let source_root = db.source_root(source_root); - for &file_id in source_root.files.iter() { + for &file_id in source_root.files.values() { let source = ModuleSource::new_file(file_id); if visited.contains(&source) { continue; // TODO: use explicit crate_roots here @@ -160,7 +161,8 @@ fn resolve_submodule( let file_id = source.file_id(); let source_root_id = db.file_source_root(file_id); let path = db.file_relative_path(file_id); - let dir_path = path.parent().unwrap(); + let root = RelativePathBuf::default(); + let dir_path = path.parent().unwrap_or(&root); let mod_name = path.file_stem().unwrap_or("unknown"); let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; @@ -174,14 +176,19 @@ fn resolve_submodule( } else { candidates.push(file_dir_mod.clone()); }; - + let sr = db.source_root(source_root_id); let points_to = candidates .into_iter() - .filter_map(|path| db.source_root_file_by_path(source_root_id, path)) + .filter_map(|path| sr.files.get(&path)) + .map(|&it| it) .collect::>(); let problem = if points_to.is_empty() { Some(Problem::UnresolvedModule { - candidate: if is_dir_owner { file_mod } else { file_dir_mod }, + candidate: RelativePath::new("../").join(&if is_dir_owner { + file_mod + } else { + file_dir_mod + }), }) } else { None -- cgit v1.2.3 From 18aac1df45ca39d01d80a56e3afab7299de160f8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 12:26:51 +0300 Subject: kill file resolver --- crates/ra_db/src/file_resolver.rs | 76 --------------------------------------- crates/ra_db/src/lib.rs | 2 -- crates/ra_db/src/mock.rs | 17 +-------- 3 files changed, 1 insertion(+), 94 deletions(-) delete mode 100644 crates/ra_db/src/file_resolver.rs diff --git a/crates/ra_db/src/file_resolver.rs b/crates/ra_db/src/file_resolver.rs deleted file mode 100644 index f849ac752..000000000 --- a/crates/ra_db/src/file_resolver.rs +++ /dev/null @@ -1,76 +0,0 @@ -use std::{ - sync::Arc, - hash::{Hash, Hasher}, - fmt, -}; - -use relative_path::RelativePath; - -use crate::input::FileId; - -pub trait FileResolver: fmt::Debug + Send + Sync + 'static { - fn file_stem(&self, file_id: FileId) -> String; - fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option; - fn debug_path(&self, _1file_id: FileId) -> Option { - None - } -} - -#[derive(Clone, Debug)] -pub struct FileResolverImp { - inner: Arc, -} - -impl PartialEq for FileResolverImp { - fn eq(&self, other: &FileResolverImp) -> bool { - self.inner() == other.inner() - } -} - -impl Eq for FileResolverImp {} - -impl Hash for FileResolverImp { - fn hash(&self, hasher: &mut H) { - self.inner().hash(hasher); - } -} - -impl FileResolverImp { - pub fn new(inner: Arc) -> FileResolverImp { - FileResolverImp { inner } - } - pub fn file_stem(&self, file_id: FileId) -> String { - self.inner.file_stem(file_id) - } - pub fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option { - self.inner.resolve(file_id, path) - } - pub fn debug_path(&self, file_id: FileId) -> Option { - self.inner.debug_path(file_id) - } - fn inner(&self) -> *const FileResolver { - &*self.inner - } -} - -impl Default for FileResolverImp { - fn default() -> FileResolverImp { - #[derive(Debug)] - struct DummyResolver; - impl FileResolver for DummyResolver { - fn file_stem(&self, _file_: FileId) -> String { - panic!("file resolver not set") - } - fn resolve( - &self, - _file_id: FileId, - _path: &::relative_path::RelativePath, - ) -> Option { - panic!("file resolver not set") - } - } - FileResolverImp { - inner: Arc::new(DummyResolver), - } - } -} diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index d1db281e6..eeb305b1b 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -1,6 +1,5 @@ //! ra_db defines basic database traits. Concrete DB is defined by ra_analysis. mod syntax_ptr; -mod file_resolver; mod input; mod loc2id; pub mod mock; @@ -24,7 +23,6 @@ impl std::error::Error for Canceled {} pub use crate::{ syntax_ptr::LocalSyntaxPtr, - file_resolver::{FileResolver, FileResolverImp}, input::{ FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, WORKSPACE, FileTextQuery, FileSourceRootQuery, SourceRootQuery, LibrariesQuery, CrateGraphQuery, diff --git a/crates/ra_db/src/mock.rs b/crates/ra_db/src/mock.rs index efe987bdd..5e185062b 100644 --- a/crates/ra_db/src/mock.rs +++ b/crates/ra_db/src/mock.rs @@ -1,7 +1,7 @@ use rustc_hash::FxHashSet; use relative_path::{RelativePath, RelativePathBuf}; -use crate::{FileId, FileResolver}; +use crate::{FileId}; #[derive(Default, Debug, Clone)] pub struct FileMap(Vec<(FileId, RelativePathBuf)>); @@ -27,19 +27,4 @@ impl FileMap { .iter() .map(|(id, path)| (*id, path.as_relative_path())) } - - fn path(&self, id: FileId) -> &RelativePath { - self.iter().find(|&(it, _)| it == id).unwrap().1 - } -} - -impl FileResolver for FileMap { - fn file_stem(&self, id: FileId) -> String { - self.path(id).file_stem().unwrap().to_string() - } - fn resolve(&self, id: FileId, rel: &RelativePath) -> Option { - let path = self.path(id).join(rel).normalize(); - let id = self.iter().find(|&(_, p)| path == p)?.0; - Some(id) - } } -- cgit v1.2.3 From 26dcc70129399cadfd985f86bbad8d5127f8a3a0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 12:40:41 +0300 Subject: fix hir mock --- crates/ra_hir/src/mock.rs | 35 +++++++++++++++++-------------- crates/ra_hir/src/module/nameres/tests.rs | 7 ++++--- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index b7193c4f3..54260101c 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use parking_lot::Mutex; use salsa::{self, Database}; -use ra_db::{LocationIntener, BaseDatabase, FilePosition, mock::FileMap, FileId, WORKSPACE, CrateGraph}; +use ra_db::{LocationIntener, BaseDatabase, FilePosition, FileId, WORKSPACE, CrateGraph, SourceRoot}; use relative_path::RelativePathBuf; use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; @@ -16,10 +16,10 @@ pub(crate) struct MockDatabase { } impl MockDatabase { - pub(crate) fn with_files(fixture: &str) -> (MockDatabase, FileMap) { - let (db, file_map, position) = MockDatabase::from_fixture(fixture); + pub(crate) fn with_files(fixture: &str) -> (MockDatabase, SourceRoot) { + let (db, source_root, position) = MockDatabase::from_fixture(fixture); assert!(position.is_none()); - (db, file_map) + (db, source_root) } pub(crate) fn with_position(fixture: &str) -> (MockDatabase, FilePosition) { @@ -33,48 +33,50 @@ impl MockDatabase { .set((), Arc::new(crate_graph)); } - fn from_fixture(fixture: &str) -> (MockDatabase, FileMap, Option) { + fn from_fixture(fixture: &str) -> (MockDatabase, SourceRoot, Option) { let mut db = MockDatabase::default(); let mut position = None; - let mut file_map = FileMap::default(); + let mut source_root = SourceRoot::default(); for entry in parse_fixture(fixture) { if entry.text.contains(CURSOR_MARKER) { assert!( position.is_none(), "only one marker (<|>) per fixture is allowed" ); - position = Some(db.add_file_with_position(&mut file_map, &entry.meta, &entry.text)); + position = + Some(db.add_file_with_position(&mut source_root, &entry.meta, &entry.text)); } else { - db.add_file(&mut file_map, &entry.meta, &entry.text); + db.add_file(&mut source_root, &entry.meta, &entry.text); } } - let source_root = file_map.clone().into_source_root(); db.query_mut(ra_db::SourceRootQuery) - .set(WORKSPACE, Arc::new(source_root)); - (db, file_map, position) + .set(WORKSPACE, Arc::new(source_root.clone())); + (db, source_root, position) } - fn add_file(&mut self, file_map: &mut FileMap, path: &str, text: &str) -> FileId { + fn add_file(&mut self, source_root: &mut SourceRoot, path: &str, text: &str) -> FileId { assert!(path.starts_with('/')); let path = RelativePathBuf::from_path(&path[1..]).unwrap(); - - let file_id = file_map.add(path); + let file_id = FileId(source_root.files.len() as u32); let text = Arc::new(text.to_string()); self.query_mut(ra_db::FileTextQuery).set(file_id, text); + self.query_mut(ra_db::FileRelativePathQuery) + .set(file_id, path.clone()); self.query_mut(ra_db::FileSourceRootQuery) .set(file_id, WORKSPACE); + source_root.files.insert(path, file_id); file_id } fn add_file_with_position( &mut self, - file_map: &mut FileMap, + source_root: &mut SourceRoot, path: &str, text: &str, ) -> FilePosition { let (offset, text) = extract_offset(text); - let file_id = self.add_file(file_map, path, &text); + let file_id = self.add_file(source_root, path, &text); FilePosition { file_id, offset } } } @@ -158,6 +160,7 @@ salsa::database_storage! { pub(crate) struct MockDatabaseStorage for MockDatabase { impl ra_db::FilesDatabase { fn file_text() for ra_db::FileTextQuery; + fn file_relative_path() for ra_db::FileRelativePathQuery; fn file_source_root() for ra_db::FileSourceRootQuery; fn source_root() for ra_db::SourceRootQuery; fn libraries() for ra_db::LibrariesQuery; diff --git a/crates/ra_hir/src/module/nameres/tests.rs b/crates/ra_hir/src/module/nameres/tests.rs index 9ddc32dcd..9fa9146e3 100644 --- a/crates/ra_hir/src/module/nameres/tests.rs +++ b/crates/ra_hir/src/module/nameres/tests.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use salsa::Database; use ra_db::{FilesDatabase, CrateGraph}; use ra_syntax::SmolStr; +use relative_path::RelativePath; use crate::{ self as hir, @@ -44,7 +45,7 @@ fn item_map_smoke_test() { #[test] fn item_map_across_crates() { - let (mut db, files) = MockDatabase::with_files( + let (mut db, sr) = MockDatabase::with_files( " //- /main.rs use test_crate::Baz; @@ -53,8 +54,8 @@ fn item_map_across_crates() { pub struct Baz; ", ); - let main_id = files.file_id("/main.rs"); - let lib_id = files.file_id("/lib.rs"); + let main_id = sr.files[RelativePath::new("/main.rs")]; + let lib_id = sr.files[RelativePath::new("/lib.rs")]; let mut crate_graph = CrateGraph::default(); let main_crate = crate_graph.add_crate_root(main_id); -- cgit v1.2.3 From 79596abcaf50019810f7fa01a264100472359f8a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 12:41:23 +0300 Subject: dead import --- crates/ra_analysis/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index bfc4e0f17..b806c974d 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -39,8 +39,7 @@ pub use hir::FnSignatureInfo; pub use ra_db::{ Canceled, Cancelable, FilePosition, - CrateGraph, CrateId, SourceRootId, FileId, FileResolver, - WORKSPACE + CrateGraph, CrateId, SourceRootId, FileId, WORKSPACE }; #[derive(Default)] -- cgit v1.2.3 From 6a755ed83a583d1f70a5fbcff2d4933b52628cfe Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 12:48:34 +0300 Subject: remove more imports --- crates/ra_lsp_server/src/path_map.rs | 23 +---------------------- crates/ra_lsp_server/src/server_world.rs | 2 +- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/crates/ra_lsp_server/src/path_map.rs b/crates/ra_lsp_server/src/path_map.rs index 02e54629c..86cf29540 100644 --- a/crates/ra_lsp_server/src/path_map.rs +++ b/crates/ra_lsp_server/src/path_map.rs @@ -4,7 +4,7 @@ use std::{ }; use im; -use ra_analysis::{FileId, FileResolver}; +use ra_analysis::{FileId}; use relative_path::RelativePath; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -64,27 +64,6 @@ impl PathMap { } } -impl FileResolver for PathMap { - fn file_stem(&self, file_id: FileId) -> String { - self.get_path(file_id) - .file_stem() - .unwrap() - .to_str() - .unwrap() - .to_string() - } - - fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option { - let path = path.to_path(&self.get_path(file_id)); - let path = normalize(&path); - self.get_id(&path) - } - - fn debug_path(&self, file_id: FileId) -> Option { - Some(self.get_path(file_id).to_owned()) - } -} - fn normalize(path: &Path) -> PathBuf { let mut components = path.components().peekable(); let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index ab4c2c8aa..c0d1338a2 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -6,7 +6,7 @@ use std::{ use languageserver_types::Url; use ra_analysis::{ - Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, FileResolver, LibraryData, + Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, }; use rustc_hash::FxHashMap; use failure::{bail, format_err}; -- cgit v1.2.3 From a5ef8ad05b7c1f7148c59814b55d641fd75aff75 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 15:04:15 +0300 Subject: swtich lsp server to vfs --- Cargo.lock | 25 +++ crates/ra_analysis/src/imp.rs | 9 +- crates/ra_analysis/src/lib.rs | 8 +- crates/ra_lsp_server/Cargo.toml | 2 + crates/ra_lsp_server/src/lib.rs | 2 - crates/ra_lsp_server/src/main_loop.rs | 143 +++++++---------- crates/ra_lsp_server/src/main_loop/handlers.rs | 4 +- crates/ra_lsp_server/src/path_map.rs | 105 ------------- crates/ra_lsp_server/src/project_model.rs | 1 + crates/ra_lsp_server/src/server_world.rs | 203 ++++++++++--------------- crates/ra_lsp_server/src/vfs.rs | 67 -------- crates/ra_vfs/src/io.rs | 7 + crates/ra_vfs/src/lib.rs | 53 ++++++- crates/thread_worker/src/lib.rs | 3 + 14 files changed, 234 insertions(+), 398 deletions(-) delete mode 100644 crates/ra_lsp_server/src/path_map.rs delete mode 100644 crates/ra_lsp_server/src/vfs.rs diff --git a/Cargo.lock b/Cargo.lock index 0a7128d0c..7ebe6e67f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,6 +541,15 @@ dependencies = [ "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot_core" version = "0.3.1" @@ -553,6 +562,18 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "percent-encoding" version = "1.0.1" @@ -701,10 +722,12 @@ dependencies = [ "im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "languageserver-types 0.53.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "ra_analysis 0.1.0", "ra_editor 0.1.0", "ra_syntax 0.1.0", "ra_text_edit 0.1.0", + "ra_vfs 0.1.0", "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1496,7 +1519,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" +"checksum parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9723236a9525c757d9725b993511e3fc941e33f27751942232f0058298297edf" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" +"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pest 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a677051ad923732bb5c70f2d45f8985a96e3eee2e2bff86697e3b11b0c3fcfde" "checksum pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b76f477146419bc539a63f4ef40e902166cb43b3e51cecc71d9136fd12c567e7" diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 51bcd5a73..54f38b285 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -43,14 +43,17 @@ impl AnalysisHostImpl { pub fn apply_change(&mut self, change: AnalysisChange) { log::info!("apply_change {:?}", change); // self.gc_syntax_trees(); + for root_id in change.new_roots { + self.db + .query_mut(ra_db::SourceRootQuery) + .set(root_id, Default::default()); + } for (root_id, root_change) in change.roots_changed { self.apply_root_change(root_id, root_change); } for (file_id, text) in change.files_changed { - self.db - .query_mut(ra_db::FileTextQuery) - .set(file_id, Arc::new(text)) + self.db.query_mut(ra_db::FileTextQuery).set(file_id, text) } if !change.libraries_added.is_empty() { let mut libraries = Vec::clone(&self.db.libraries()); diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index b806c974d..8882feca3 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -44,8 +44,9 @@ pub use ra_db::{ #[derive(Default)] pub struct AnalysisChange { + new_roots: Vec, roots_changed: FxHashMap, - files_changed: Vec<(FileId, String)>, + files_changed: Vec<(FileId, Arc)>, libraries_added: Vec, crate_graph: Option, } @@ -93,6 +94,9 @@ impl AnalysisChange { pub fn new() -> AnalysisChange { AnalysisChange::default() } + pub fn add_root(&mut self, root_id: SourceRootId) { + self.new_roots.push(root_id); + } pub fn add_file( &mut self, root_id: SourceRootId, @@ -111,7 +115,7 @@ impl AnalysisChange { .added .push(file); } - pub fn change_file(&mut self, file_id: FileId, new_text: String) { + pub fn change_file(&mut self, file_id: FileId, new_text: Arc) { self.files_changed.push((file_id, new_text)) } pub fn remove_file(&mut self, root_id: SourceRootId, file_id: FileId, path: RelativePathBuf) { diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index 4e8e09584..fc10096e5 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml @@ -25,6 +25,7 @@ cargo_metadata = "0.6.0" text_unit = { version = "0.1.2", features = ["serde"] } smol_str = { version = "0.1.5", features = ["serde"] } rustc-hash = "1.0" +parking_lot = "0.7.0" thread_worker = { path = "../thread_worker" } ra_syntax = { path = "../ra_syntax" } @@ -32,6 +33,7 @@ ra_editor = { path = "../ra_editor" } ra_text_edit = { path = "../ra_text_edit" } ra_analysis = { path = "../ra_analysis" } gen_lsp_server = { path = "../gen_lsp_server" } +ra_vfs = { path = "../ra_vfs" } [dev-dependencies] tempdir = "0.3.7" diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index 1d7258c35..725b1258a 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs @@ -1,11 +1,9 @@ mod caps; mod conv; mod main_loop; -mod path_map; mod project_model; pub mod req; mod server_world; -mod vfs; pub type Result = ::std::result::Result; pub use crate::{caps::server_capabilities, main_loop::main_loop, main_loop::LspError}; diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 9d3f83b4c..7904545d3 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -1,7 +1,10 @@ mod handlers; mod subscriptions; -use std::path::PathBuf; +use std::{ + path::PathBuf, + sync::Arc, +}; use crossbeam_channel::{unbounded, select, Receiver, Sender}; use gen_lsp_server::{ @@ -9,8 +12,8 @@ use gen_lsp_server::{ }; use languageserver_types::NumberOrString; use ra_analysis::{Canceled, FileId, LibraryData}; +use ra_vfs::{VfsTask}; use rayon; -use thread_worker::Worker; use threadpool::ThreadPool; use rustc_hash::FxHashSet; use serde::{de::DeserializeOwned, Serialize}; @@ -19,10 +22,9 @@ use failure_derive::Fail; use crate::{ main_loop::subscriptions::Subscriptions, - project_model::{workspace_loader, CargoWorkspace}, + project_model::{workspace_loader}, req, server_world::{ServerWorld, ServerWorldState}, - vfs::{self, FileEvent}, Result, }; @@ -50,32 +52,42 @@ enum Task { pub fn main_loop( internal_mode: bool, - root: PathBuf, + ws_root: PathBuf, publish_decorations: bool, msg_receiver: &Receiver, msg_sender: &Sender, ) -> Result<()> { let pool = ThreadPool::new(8); let (task_sender, task_receiver) = unbounded::(); - let (fs_worker, fs_watcher) = vfs::roots_loader(); let (ws_worker, ws_watcher) = workspace_loader(); + ws_worker.send(ws_root.clone()); + // FIXME: support dynamic workspace loading. + let workspaces = match ws_worker.recv().unwrap() { + Ok(ws) => vec![ws], + Err(e) => { + log::warn!("loading workspace failed: {}", e); + Vec::new() + } + }; + ws_worker.shutdown(); + ws_watcher + .shutdown() + .map_err(|_| format_err!("ws watcher died"))?; + let mut state = ServerWorldState::new(ws_root.clone(), workspaces); + log::info!("server initialized, serving requests"); - let mut state = ServerWorldState::default(); let mut pending_requests = FxHashSet::default(); let mut subs = Subscriptions::new(); let main_res = main_loop_inner( internal_mode, publish_decorations, - root, &pool, msg_sender, msg_receiver, task_sender, task_receiver.clone(), - fs_worker, - ws_worker, &mut state, &mut pending_requests, &mut subs, @@ -88,12 +100,11 @@ pub fn main_loop( drop(pool); log::info!("...threadpool has finished"); - let fs_res = fs_watcher.shutdown(); - let ws_res = ws_watcher.shutdown(); + let vfs = Arc::try_unwrap(state.vfs).expect("all snapshots should be dead"); + let vfs_res = vfs.into_inner().shutdown(); main_res?; - fs_res.map_err(|_| format_err!("fs watcher died"))?; - ws_res.map_err(|_| format_err!("ws watcher died"))?; + vfs_res.map_err(|_| format_err!("fs watcher died"))?; Ok(()) } @@ -101,28 +112,22 @@ pub fn main_loop( fn main_loop_inner( internal_mode: bool, publish_decorations: bool, - ws_root: PathBuf, pool: &ThreadPool, msg_sender: &Sender, msg_receiver: &Receiver, task_sender: Sender, task_receiver: Receiver, - fs_worker: Worker)>, - ws_worker: Worker>, state: &mut ServerWorldState, pending_requests: &mut FxHashSet, subs: &mut Subscriptions, ) -> Result<()> { let (libdata_sender, libdata_receiver) = unbounded(); - ws_worker.send(ws_root.clone()); - fs_worker.send(ws_root.clone()); loop { #[derive(Debug)] enum Event { Msg(RawMessage), Task(Task), - Fs(PathBuf, Vec), - Ws(Result), + Vfs(VfsTask), Lib(LibraryData), } log::trace!("selecting"); @@ -132,77 +137,19 @@ fn main_loop_inner( None => bail!("client exited without shutdown"), }, recv(task_receiver, task) => Event::Task(task.unwrap()), - recv(fs_worker.out, events) => match events { - None => bail!("roots watcher died"), - Some((pb, events)) => Event::Fs(pb, events), - } - recv(ws_worker.out, ws) => match ws { - None => bail!("workspace watcher died"), - Some(ws) => Event::Ws(ws), + recv(state.vfs.read().task_receiver(), task) => match task { + None => bail!("vfs died"), + Some(task) => Event::Vfs(task), } recv(libdata_receiver, data) => Event::Lib(data.unwrap()) }; let mut state_changed = false; match event { Event::Task(task) => on_task(task, msg_sender, pending_requests), - Event::Fs(root, events) => { - log::info!("fs change, {}, {} events", root.display(), events.len()); - if root == ws_root { - state.apply_fs_changes(events); - } else { - let (files, resolver) = state.events_to_files(events); - let sender = libdata_sender.clone(); - pool.execute(move || { - let start = ::std::time::Instant::now(); - log::info!("indexing {} ... ", root.display()); - let data = LibraryData::prepare(files, resolver); - log::info!("indexed {:?} {}", start.elapsed(), root.display()); - sender.send(data); - }); - } + Event::Vfs(task) => { + state.vfs.write().handle_task(task); state_changed = true; } - Event::Ws(ws) => match ws { - Ok(ws) => { - let workspaces = vec![ws]; - feedback(internal_mode, "workspace loaded", msg_sender); - for ws in workspaces.iter() { - // Add each library as constant input. If library is - // within the workspace, don't treat it as a library. - // - // HACK: If source roots are nested, pick the outer one. - - let mut roots = ws - .packages() - .filter(|pkg| !pkg.is_member(ws)) - .filter_map(|pkg| { - let root = pkg.root(ws).to_path_buf(); - if root.starts_with(&ws_root) { - None - } else { - Some(root) - } - }) - .collect::>(); - roots.sort_by_key(|it| it.as_os_str().len()); - let unique = roots - .iter() - .enumerate() - .filter(|&(idx, long)| { - !roots[..idx].iter().any(|short| long.starts_with(short)) - }) - .map(|(_idx, root)| root); - - for root in unique { - log::debug!("sending root, {}", root.display()); - fs_worker.send(root.to_owned()); - } - } - state.set_workspaces(workspaces); - state_changed = true; - } - Err(e) => log::warn!("loading workspace failed: {}", e), - }, Event::Lib(lib) => { feedback(internal_mode, "library loaded", msg_sender); state.add_lib(lib); @@ -234,6 +181,18 @@ fn main_loop_inner( }, }; + for lib in state.process_changes() { + let (root, files) = lib; + let sender = libdata_sender.clone(); + pool.execute(move || { + let start = ::std::time::Instant::now(); + log::info!("indexing {:?} ... ", root); + let data = LibraryData::prepare(root, files); + log::info!("indexed {:?} {:?}", start.elapsed(), root); + sender.send(data); + }); + } + if state_changed { update_file_notifications_on_threadpool( pool, @@ -336,8 +295,13 @@ fn on_notification( let path = uri .to_file_path() .map_err(|()| format_err!("invalid uri: {}", uri))?; - let file_id = state.add_mem_file(path, params.text_document.text); - subs.add_sub(file_id); + if let Some(file_id) = state + .vfs + .write() + .add_file_overlay(&path, params.text_document.text) + { + subs.add_sub(FileId(file_id.0)); + } return Ok(()); } Err(not) => not, @@ -353,7 +317,7 @@ fn on_notification( .pop() .ok_or_else(|| format_err!("empty changes"))? .text; - state.change_mem_file(path.as_path(), text)?; + state.vfs.write().change_file_overlay(path.as_path(), text); return Ok(()); } Err(not) => not, @@ -364,8 +328,9 @@ fn on_notification( let path = uri .to_file_path() .map_err(|()| format_err!("invalid uri: {}", uri))?; - let file_id = state.remove_mem_file(path.as_path())?; - subs.remove_sub(file_id); + if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { + subs.remove_sub(FileId(file_id.0)); + } let params = req::PublishDiagnosticsParams { uri, diagnostics: Vec::new(), diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index acca480c7..572ae7fb5 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -326,9 +326,9 @@ pub fn handle_runnables( None => return Ok(None), }; let file_id = world.analysis().crate_root(crate_id)?; - let path = world.path_map.get_path(file_id); + let path = world.vfs.read().file2path(ra_vfs::VfsFile(file_id.0)); let res = world.workspaces.iter().find_map(|ws| { - let tgt = ws.target_by_root(path)?; + let tgt = ws.target_by_root(&path)?; let res = CargoTargetSpec { package: tgt.package(ws).name(ws).to_string(), target: tgt.name(ws).to_string(), diff --git a/crates/ra_lsp_server/src/path_map.rs b/crates/ra_lsp_server/src/path_map.rs deleted file mode 100644 index 86cf29540..000000000 --- a/crates/ra_lsp_server/src/path_map.rs +++ /dev/null @@ -1,105 +0,0 @@ -use std::{ - fmt, - path::{Component, Path, PathBuf}, -}; - -use im; -use ra_analysis::{FileId}; -use relative_path::RelativePath; - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Root { - Workspace, - Lib, -} - -#[derive(Default, Clone)] -pub struct PathMap { - next_id: u32, - path2id: im::HashMap, - id2path: im::HashMap, - id2root: im::HashMap, -} - -impl fmt::Debug for PathMap { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("PathMap { ... }") - } -} - -impl PathMap { - pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> (bool, FileId) { - let mut inserted = false; - let file_id = self - .path2id - .get(path.as_path()) - .map(|&id| id) - .unwrap_or_else(|| { - inserted = true; - let id = self.new_file_id(); - self.insert(path, id, root); - id - }); - (inserted, file_id) - } - pub fn get_id(&self, path: &Path) -> Option { - self.path2id.get(path).cloned() - } - pub fn get_path(&self, file_id: FileId) -> &Path { - self.id2path.get(&file_id).unwrap().as_path() - } - pub fn get_root(&self, file_id: FileId) -> Root { - self.id2root[&file_id] - } - fn insert(&mut self, path: PathBuf, file_id: FileId, root: Root) { - self.path2id.insert(path.clone(), file_id); - self.id2path.insert(file_id, path.clone()); - self.id2root.insert(file_id, root); - } - - fn new_file_id(&mut self) -> FileId { - let id = FileId(self.next_id); - self.next_id += 1; - id - } -} - -fn normalize(path: &Path) -> PathBuf { - let mut components = path.components().peekable(); - let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { - components.next(); - PathBuf::from(c.as_os_str()) - } else { - PathBuf::new() - }; - - for component in components { - match component { - Component::Prefix(..) => unreachable!(), - Component::RootDir => { - ret.push(component.as_os_str()); - } - Component::CurDir => {} - Component::ParentDir => { - ret.pop(); - } - Component::Normal(c) => { - ret.push(c); - } - } - } - ret -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_resolve() { - let mut m = PathMap::default(); - let (_, id1) = m.get_or_insert(PathBuf::from("/foo"), Root::Workspace); - let (_, id2) = m.get_or_insert(PathBuf::from("/foo/bar.rs"), Root::Workspace); - assert_eq!(m.resolve(id1, &RelativePath::new("bar.rs")), Some(id2),) - } -} diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs index b881f8b6f..5852a157d 100644 --- a/crates/ra_lsp_server/src/project_model.rs +++ b/crates/ra_lsp_server/src/project_model.rs @@ -69,6 +69,7 @@ impl Package { pub fn targets<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator + 'a { ws.pkg(self).targets.iter().cloned() } + #[allow(unused)] pub fn is_member(self, ws: &CargoWorkspace) -> bool { ws.pkg(self).is_member } diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index c0d1338a2..f2fd09e85 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -1,154 +1,62 @@ use std::{ - fs, - path::{Path, PathBuf}, + path::{PathBuf}, sync::Arc, }; use languageserver_types::Url; use ra_analysis::{ Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, + SourceRootId }; +use ra_vfs::{Vfs, VfsChange, VfsFile}; use rustc_hash::FxHashMap; -use failure::{bail, format_err}; +use relative_path::RelativePathBuf; +use parking_lot::RwLock; +use failure::{format_err}; use crate::{ - path_map::{PathMap, Root}, project_model::{CargoWorkspace, TargetKind}, - vfs::{FileEvent, FileEventKind}, Result, }; -#[derive(Debug, Default)] +#[derive(Debug)] pub struct ServerWorldState { pub workspaces: Arc>, pub analysis_host: AnalysisHost, - pub path_map: PathMap, - pub mem_map: FxHashMap>, + pub vfs: Arc>, } pub struct ServerWorld { pub workspaces: Arc>, pub analysis: Analysis, - pub path_map: PathMap, + pub vfs: Arc>, } impl ServerWorldState { - pub fn apply_fs_changes(&mut self, events: Vec) { + pub fn new(root: PathBuf, workspaces: Vec) -> ServerWorldState { let mut change = AnalysisChange::new(); - let mut inserted = false; - { - let pm = &mut self.path_map; - let mm = &mut self.mem_map; - events - .into_iter() - .map(|event| { - let text = match event.kind { - FileEventKind::Add(text) => text, - }; - (event.path, text) - }) - .map(|(path, text)| { - let (ins, file_id) = pm.get_or_insert(path, Root::Workspace); - inserted |= ins; - (file_id, text) - }) - .filter_map(|(file_id, text)| { - if mm.contains_key(&file_id) { - mm.insert(file_id, Some(text)); - None - } else { - Some((file_id, text)) - } - }) - .for_each(|(file_id, text)| change.add_file(file_id, text)); - } - if inserted { - change.set_file_resolver(Arc::new(self.path_map.clone())) - } - self.analysis_host.apply_change(change); - } - pub fn events_to_files( - &mut self, - events: Vec, - ) -> (Vec<(FileId, String)>, Arc) { - let files = { - let pm = &mut self.path_map; - events - .into_iter() - .map(|event| { - let FileEventKind::Add(text) = event.kind; - (event.path, text) - }) - .map(|(path, text)| (pm.get_or_insert(path, Root::Lib).1, text)) - .collect() - }; - let resolver = Arc::new(self.path_map.clone()); - (files, resolver) - } - pub fn add_lib(&mut self, data: LibraryData) { - let mut change = AnalysisChange::new(); - change.add_library(data); - self.analysis_host.apply_change(change); - } - pub fn add_mem_file(&mut self, path: PathBuf, text: String) -> FileId { - let (inserted, file_id) = self.path_map.get_or_insert(path, Root::Workspace); - if self.path_map.get_root(file_id) != Root::Lib { - let mut change = AnalysisChange::new(); - if inserted { - change.add_file(file_id, text); - change.set_file_resolver(Arc::new(self.path_map.clone())); - } else { - change.change_file(file_id, text); + let mut roots = Vec::new(); + roots.push(root); + for ws in workspaces.iter() { + for pkg in ws.packages() { + roots.push(pkg.root(&ws).to_path_buf()); } - self.analysis_host.apply_change(change); } - self.mem_map.insert(file_id, None); - file_id - } - - pub fn change_mem_file(&mut self, path: &Path, text: String) -> Result<()> { - let file_id = self - .path_map - .get_id(path) - .ok_or_else(|| format_err!("change to unknown file: {}", path.display()))?; - if self.path_map.get_root(file_id) != Root::Lib { - let mut change = AnalysisChange::new(); - change.change_file(file_id, text); - self.analysis_host.apply_change(change); + let (mut vfs, roots) = Vfs::new(roots); + for r in roots { + change.add_root(SourceRootId(r.0)); } - Ok(()) - } - pub fn remove_mem_file(&mut self, path: &Path) -> Result { - let file_id = self - .path_map - .get_id(path) - .ok_or_else(|| format_err!("change to unknown file: {}", path.display()))?; - match self.mem_map.remove(&file_id) { - Some(_) => (), - None => bail!("unmatched close notification"), - }; - // Do this via file watcher ideally. - let text = fs::read_to_string(path).ok(); - if self.path_map.get_root(file_id) != Root::Lib { - let mut change = AnalysisChange::new(); - if let Some(text) = text { - change.change_file(file_id, text); - } - self.analysis_host.apply_change(change); - } - Ok(file_id) - } - pub fn set_workspaces(&mut self, ws: Vec) { let mut crate_graph = CrateGraph::default(); let mut pkg_to_lib_crate = FxHashMap::default(); let mut pkg_crates = FxHashMap::default(); - for ws in ws.iter() { + for ws in workspaces.iter() { for pkg in ws.packages() { for tgt in pkg.targets(ws) { let root = tgt.root(ws); - if let Some(file_id) = self.path_map.get_id(root) { + if let Some(file_id) = vfs.load(root) { + let file_id = FileId(file_id.0); let crate_id = crate_graph.add_crate_root(file_id); if tgt.kind(ws) == TargetKind::Lib { pkg_to_lib_crate.insert(pkg, crate_id); @@ -170,16 +78,64 @@ impl ServerWorldState { } } } - self.workspaces = Arc::new(ws); - let mut change = AnalysisChange::new(); change.set_crate_graph(crate_graph); + + let mut analysis_host = AnalysisHost::default(); + analysis_host.apply_change(change); + ServerWorldState { + workspaces: Arc::new(workspaces), + analysis_host, + vfs: Arc::new(RwLock::new(vfs)), + } + } + + /// Returns a vec of libraries + /// FIXME: better API here + pub fn process_changes( + &mut self, + ) -> Vec<(SourceRootId, Vec<(FileId, RelativePathBuf, Arc)>)> { + let mut libs = Vec::new(); + let mut change = AnalysisChange::new(); + for c in self.vfs.write().commit_changes() { + match c { + VfsChange::AddRoot { root, files } => { + let files = files + .into_iter() + .map(|(vfsfile, path, text)| (FileId(vfsfile.0), path, text)) + .collect(); + libs.push((SourceRootId(root.0), files)); + } + VfsChange::AddFile { + root, + file, + path, + text, + } => { + change.add_file(SourceRootId(root.0), FileId(file.0), path, text); + } + VfsChange::RemoveFile { root, file, path } => { + change.remove_file(SourceRootId(root.0), FileId(file.0), path) + } + VfsChange::ChangeFile { file, text } => { + change.change_file(FileId(file.0), text); + } + } + } self.analysis_host.apply_change(change); + libs } + + pub fn add_lib(&mut self, data: LibraryData) { + let mut change = AnalysisChange::new(); + change.add_library(data); + self.analysis_host.apply_change(change); + } + pub fn snapshot(&self) -> ServerWorld { ServerWorld { workspaces: Arc::clone(&self.workspaces), analysis: self.analysis_host.analysis(), - path_map: self.path_map.clone(), + vfs: Arc::clone(&self.vfs), } } } @@ -193,15 +149,18 @@ impl ServerWorld { let path = uri .to_file_path() .map_err(|()| format_err!("invalid uri: {}", uri))?; - self.path_map - .get_id(&path) - .ok_or_else(|| format_err!("unknown file: {}", path.display())) + let file = self + .vfs + .read() + .path2file(&path) + .ok_or_else(|| format_err!("unknown file: {}", path.display()))?; + Ok(FileId(file.0)) } pub fn file_id_to_uri(&self, id: FileId) -> Result { - let path = self.path_map.get_path(id); - let url = Url::from_file_path(path) - .map_err(|()| format_err!("can't convert path to url: {}", path.display()))?; + let path = self.vfs.read().file2path(VfsFile(id.0)); + let url = Url::from_file_path(&path) + .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; Ok(url) } } diff --git a/crates/ra_lsp_server/src/vfs.rs b/crates/ra_lsp_server/src/vfs.rs deleted file mode 100644 index fcf7693d8..000000000 --- a/crates/ra_lsp_server/src/vfs.rs +++ /dev/null @@ -1,67 +0,0 @@ -use std::{ - fs, - path::{Path, PathBuf}, -}; - -use walkdir::WalkDir; -use thread_worker::{WorkerHandle, Worker}; - -#[derive(Debug)] -pub struct FileEvent { - pub path: PathBuf, - pub kind: FileEventKind, -} - -#[derive(Debug)] -pub enum FileEventKind { - Add(String), -} - -pub fn roots_loader() -> (Worker)>, WorkerHandle) { - thread_worker::spawn::), _>( - "roots loader", - 128, - |input_receiver, output_sender| { - input_receiver - .map(|path| { - log::debug!("loading {} ...", path.as_path().display()); - let events = load_root(path.as_path()); - log::debug!("... loaded {}", path.as_path().display()); - (path, events) - }) - .for_each(|it| output_sender.send(it)) - }, - ) -} - -fn load_root(path: &Path) -> Vec { - let mut res = Vec::new(); - for entry in WalkDir::new(path) { - let entry = match entry { - Ok(entry) => entry, - Err(e) => { - log::warn!("watcher error: {}", e); - continue; - } - }; - if !entry.file_type().is_file() { - continue; - } - let path = entry.path(); - if path.extension().and_then(|os| os.to_str()) != Some("rs") { - continue; - } - let text = match fs::read_to_string(path) { - Ok(text) => text, - Err(e) => { - log::warn!("watcher error: {}", e); - continue; - } - }; - res.push(FileEvent { - path: path.to_owned(), - kind: FileEventKind::Add(text), - }) - } - res -} diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs index 178c9beff..be400bae9 100644 --- a/crates/ra_vfs/src/io.rs +++ b/crates/ra_vfs/src/io.rs @@ -1,4 +1,5 @@ use std::{ + fmt, fs, path::{Path, PathBuf}, }; @@ -20,6 +21,12 @@ pub struct TaskResult { pub(crate) files: Vec<(RelativePathBuf, String)>, } +impl fmt::Debug for TaskResult { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TaskResult { ... }") + } +} + pub(crate) type Worker = thread_worker::Worker; pub(crate) fn start() -> (Worker, WorkerHandle) { diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 6c1af5ef9..dc980c3d2 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -15,6 +15,7 @@ mod arena; mod io; use std::{ + fmt, mem, thread, cmp::Reverse, @@ -34,6 +35,8 @@ use crate::{ arena::{ArenaId, Arena}, }; +pub use crate::io::TaskResult as VfsTask; + /// `RootFilter` is a predicate that checks if a file can belong to a root. If /// several filters match a file (nested dirs), the most nested one wins. struct RootFilter { @@ -68,7 +71,7 @@ fn has_rs_extension(p: &Path) -> bool { } #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] -pub struct VfsRoot(u32); +pub struct VfsRoot(pub u32); impl ArenaId for VfsRoot { fn from_u32(idx: u32) -> VfsRoot { @@ -80,7 +83,7 @@ impl ArenaId for VfsRoot { } #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] -pub struct VfsFile(u32); +pub struct VfsFile(pub u32); impl ArenaId for VfsFile { fn from_u32(idx: u32) -> VfsFile { @@ -106,8 +109,14 @@ pub struct Vfs { worker_handle: WorkerHandle, } +impl fmt::Debug for Vfs { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Vfs { ... }") + } +} + impl Vfs { - pub fn new(mut roots: Vec) -> Vfs { + pub fn new(mut roots: Vec) -> (Vfs, Vec) { let (worker, worker_handle) = io::start(); let mut res = Vfs { @@ -142,7 +151,32 @@ impl Vfs { }; res.worker.inp.send(task); } - res + let roots = res.roots.iter().map(|(id, _)| id).collect(); + (res, roots) + } + + pub fn path2file(&self, path: &Path) -> Option { + if let Some((_root, _path, Some(file))) = self.find_root(path) { + return Some(file); + } + None + } + + pub fn file2path(&self, file: VfsFile) -> PathBuf { + let rel_path = &self.files[file].path; + let root_path = &self.roots[self.files[file].root].root; + rel_path.to_path(root_path) + } + + pub fn file_for_path(&self, path: &Path) -> Option { + if let Some((_root, _path, Some(file))) = self.find_root(path) { + return Some(file); + } + None + } + + pub fn load(&mut self, path: &Path) -> Option { + None } pub fn task_receiver(&self) -> &Receiver { @@ -163,14 +197,17 @@ impl Vfs { self.pending_changes.push(change); } - pub fn add_file_overlay(&mut self, path: &Path, text: String) { + pub fn add_file_overlay(&mut self, path: &Path, text: String) -> Option { + let mut res = None; if let Some((root, path, file)) = self.find_root(path) { let text = Arc::new(text); let change = if let Some(file) = file { + res = Some(file); self.change_file(file, Arc::clone(&text)); VfsChange::ChangeFile { file, text } } else { let file = self.add_file(root, path.clone(), Arc::clone(&text)); + res = Some(file); VfsChange::AddFile { file, text, @@ -180,6 +217,7 @@ impl Vfs { }; self.pending_changes.push(change); } + res } pub fn change_file_overlay(&mut self, path: &Path, new_text: String) { @@ -192,9 +230,11 @@ impl Vfs { } } - pub fn remove_file_overlay(&mut self, path: &Path) { + pub fn remove_file_overlay(&mut self, path: &Path) -> Option { + let mut res = None; if let Some((root, path, file)) = self.find_root(path) { let file = file.expect("can't remove a file which wasn't added"); + res = Some(file); let full_path = path.to_path(&self.roots[root].root); let change = if let Ok(text) = fs::read_to_string(&full_path) { let text = Arc::new(text); @@ -206,6 +246,7 @@ impl Vfs { }; self.pending_changes.push(change); } + res } pub fn commit_changes(&mut self) -> Vec { diff --git a/crates/thread_worker/src/lib.rs b/crates/thread_worker/src/lib.rs index 24d7fcce1..12e8bf17e 100644 --- a/crates/thread_worker/src/lib.rs +++ b/crates/thread_worker/src/lib.rs @@ -37,6 +37,9 @@ impl Worker { pub fn send(&self, item: I) { self.inp.send(item) } + pub fn recv(&self) -> Option { + self.out.recv() + } } impl WorkerHandle { -- cgit v1.2.3 From 7b6bafa631e6272946da568e9da7c3adc01ba625 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 15:40:42 +0300 Subject: fix syc --- crates/ra_analysis/src/lib.rs | 1 + crates/ra_lsp_server/src/main_loop.rs | 4 ++++ crates/ra_lsp_server/src/server_world.rs | 33 ++++++++++++++++++++------ crates/ra_lsp_server/tests/heavy_tests/main.rs | 3 +-- crates/ra_vfs/src/lib.rs | 27 +++++++++++++++++---- 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 8882feca3..300dfc5dd 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -73,6 +73,7 @@ struct RemoveFile { impl fmt::Debug for AnalysisChange { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("AnalysisChange") + .field("new_roots", &self.new_roots) .field("roots_changed", &self.roots_changed) .field("files_changed", &self.files_changed.len()) .field("libraries_added", &self.libraries_added.len()) diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 7904545d3..d2f16ea97 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -143,6 +143,7 @@ fn main_loop_inner( } recv(libdata_receiver, data) => Event::Lib(data.unwrap()) }; + log::info!("{:?}", event); let mut state_changed = false; match event { Event::Task(task) => on_task(task, msg_sender, pending_requests), @@ -192,6 +193,9 @@ fn main_loop_inner( sender.send(data); }); } + if state.roots_to_scan == 0 { + feedback(internal_mode, "workspace loaded", msg_sender); + } if state_changed { update_file_notifications_on_threadpool( diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index f2fd09e85..bdb4c513f 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -21,6 +21,8 @@ use crate::{ #[derive(Debug)] pub struct ServerWorldState { + pub roots_to_scan: usize, + pub root: PathBuf, pub workspaces: Arc>, pub analysis_host: AnalysisHost, pub vfs: Arc>, @@ -37,12 +39,13 @@ impl ServerWorldState { let mut change = AnalysisChange::new(); let mut roots = Vec::new(); - roots.push(root); + roots.push(root.clone()); for ws in workspaces.iter() { for pkg in ws.packages() { roots.push(pkg.root(&ws).to_path_buf()); } } + let roots_to_scan = roots.len(); let (mut vfs, roots) = Vfs::new(roots); for r in roots { change.add_root(SourceRootId(r.0)); @@ -83,6 +86,8 @@ impl ServerWorldState { let mut analysis_host = AnalysisHost::default(); analysis_host.apply_change(change); ServerWorldState { + roots_to_scan, + root, workspaces: Arc::new(workspaces), analysis_host, vfs: Arc::new(RwLock::new(vfs)), @@ -94,16 +99,29 @@ impl ServerWorldState { pub fn process_changes( &mut self, ) -> Vec<(SourceRootId, Vec<(FileId, RelativePathBuf, Arc)>)> { + let changes = self.vfs.write().commit_changes(); + if changes.is_empty() { + return Vec::new(); + } let mut libs = Vec::new(); let mut change = AnalysisChange::new(); - for c in self.vfs.write().commit_changes() { + for c in changes { + log::info!("vfs change {:?}", c); match c { VfsChange::AddRoot { root, files } => { - let files = files - .into_iter() - .map(|(vfsfile, path, text)| (FileId(vfsfile.0), path, text)) - .collect(); - libs.push((SourceRootId(root.0), files)); + let root_path = self.vfs.read().root2path(root); + if root_path.starts_with(&self.root) { + self.roots_to_scan -= 1; + for (file, path, text) in files { + change.add_file(SourceRootId(root.0), FileId(file.0), path, text); + } + } else { + let files = files + .into_iter() + .map(|(vfsfile, path, text)| (FileId(vfsfile.0), path, text)) + .collect(); + libs.push((SourceRootId(root.0), files)); + } } VfsChange::AddFile { root, @@ -126,6 +144,7 @@ impl ServerWorldState { } pub fn add_lib(&mut self, data: LibraryData) { + self.roots_to_scan -= 1; let mut change = AnalysisChange::new(); change.add_library(data); self.analysis_host.apply_change(change); diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs index 26f5e3f20..029a55d40 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/main.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs @@ -1,9 +1,7 @@ mod support; use serde_json::json; - use ra_lsp_server::req::{Runnables, RunnablesParams, CodeActionRequest, CodeActionParams}; - use languageserver_types::{Position, Range, CodeActionContext}; use crate::support::project; @@ -20,6 +18,7 @@ fn foo() { } ", ); + server.wait_for_feedback("workspace loaded"); server.request::( RunnablesParams { text_document: server.doc_id("lib.rs"), diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index dc980c3d2..3a68039f0 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -132,6 +132,7 @@ impl Vfs { roots.sort_by_key(|it| Reverse(it.as_os_str().len())); for (i, path) in roots.iter().enumerate() { let root = res.roots.alloc(RootFilter::new(path.clone())); + res.root2files.insert(root, Default::default()); let nested = roots[..i] .iter() .filter(|it| it.starts_with(path)) @@ -155,6 +156,10 @@ impl Vfs { (res, roots) } + pub fn root2path(&self, root: VfsRoot) -> PathBuf { + self.roots[root].root.clone() + } + pub fn path2file(&self, path: &Path) -> Option { if let Some((_root, _path, Some(file))) = self.find_root(path) { return Some(file); @@ -176,6 +181,23 @@ impl Vfs { } pub fn load(&mut self, path: &Path) -> Option { + if let Some((root, rel_path, file)) = self.find_root(path) { + return if let Some(file) = file { + Some(file) + } else { + let text = fs::read_to_string(path).unwrap_or_default(); + let text = Arc::new(text); + let file = self.add_file(root, rel_path.clone(), Arc::clone(&text)); + let change = VfsChange::AddFile { + file, + text, + root, + path: rel_path, + }; + self.pending_changes.push(change); + Some(file) + }; + } None } @@ -262,10 +284,7 @@ impl Vfs { fn add_file(&mut self, root: VfsRoot, path: RelativePathBuf, text: Arc) -> VfsFile { let data = VfsFileData { root, path, text }; let file = self.files.alloc(data); - self.root2files - .entry(root) - .or_insert_with(FxHashSet::default) - .insert(file); + self.root2files.get_mut(&root).unwrap().insert(file); file } -- cgit v1.2.3 From 1b946ef8a61fa520459435d4e1cd674e0c550771 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 15:56:51 +0300 Subject: File can be opened before the root is scanned --- crates/ra_vfs/src/lib.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 3a68039f0..4de07b093 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -207,11 +207,23 @@ impl Vfs { pub fn handle_task(&mut self, task: io::TaskResult) { let mut files = Vec::new(); + // While we were scanning the root in the backgound, a file might have + // been open in the editor, so we need to account for that. + let exising = self.root2files[&task.root] + .iter() + .map(|&file| (self.files[file].path.clone(), file)) + .collect::>(); for (path, text) in task.files { + if let Some(&file) = exising.get(&path) { + let text = Arc::clone(&self.files[file].text); + files.push((file, path, text)); + continue; + } let text = Arc::new(text); let file = self.add_file(task.root, path.clone(), Arc::clone(&text)); files.push((file, path, text)); } + let change = VfsChange::AddRoot { root: task.root, files, -- cgit v1.2.3 From 51fec4ef844d7fe83bf96c74e02e5f820837ff2d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 15:58:34 +0300 Subject: fix the test --- crates/ra_vfs/tests/vfs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ra_vfs/tests/vfs.rs b/crates/ra_vfs/tests/vfs.rs index 4f44215c8..f56fc4603 100644 --- a/crates/ra_vfs/tests/vfs.rs +++ b/crates/ra_vfs/tests/vfs.rs @@ -25,7 +25,7 @@ fn test_vfs_works() -> std::io::Result<()> { let a_root = dir.path().join("a"); let b_root = dir.path().join("a/b"); - let mut vfs = Vfs::new(vec![a_root, b_root]); + let (mut vfs, _) = Vfs::new(vec![a_root, b_root]); for _ in 0..2 { let task = vfs.task_receiver().recv().unwrap(); vfs.handle_task(task); -- cgit v1.2.3 From e6465e7e2a7e136edd652d5f4c93b961dd652cbc Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 16:13:16 +0300 Subject: index all local crates --- crates/ra_analysis/src/db.rs | 9 ++++---- crates/ra_analysis/src/imp.rs | 39 ++++++++++++++++----------------- crates/ra_analysis/src/lib.rs | 2 +- crates/ra_analysis/src/mock_analysis.rs | 6 +++-- crates/ra_db/src/input.rs | 10 +++++---- crates/ra_db/src/lib.rs | 4 ++-- 6 files changed, 37 insertions(+), 33 deletions(-) diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index b79baf037..3d0f13f34 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs @@ -30,11 +30,11 @@ impl Default for RootDatabase { runtime: salsa::Runtime::default(), id_maps: Default::default(), }; - db.query_mut(ra_db::SourceRootQuery) - .set(ra_db::WORKSPACE, Default::default()); db.query_mut(ra_db::CrateGraphQuery) .set((), Default::default()); - db.query_mut(ra_db::LibrariesQuery) + db.query_mut(ra_db::LocalRootsQuery) + .set((), Default::default()); + db.query_mut(ra_db::LibraryRootsQuery) .set((), Default::default()); db } @@ -64,7 +64,8 @@ salsa::database_storage! { fn file_relative_path() for ra_db::FileRelativePathQuery; fn file_source_root() for ra_db::FileSourceRootQuery; fn source_root() for ra_db::SourceRootQuery; - fn libraries() for ra_db::LibrariesQuery; + fn local_roots() for ra_db::LocalRootsQuery; + fn library_roots() for ra_db::LibraryRootsQuery; fn crate_graph() for ra_db::CrateGraphQuery; } impl ra_db::SyntaxDatabase { diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 54f38b285..46169d863 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -10,7 +10,7 @@ use ra_syntax::{ SyntaxKind::*, SyntaxNodeRef, TextRange, TextUnit, }; -use ra_db::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE, SyntaxDatabase}; +use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase}; use rayon::prelude::*; use salsa::{Database, ParallelDatabase}; use hir::{ @@ -56,7 +56,7 @@ impl AnalysisHostImpl { self.db.query_mut(ra_db::FileTextQuery).set(file_id, text) } if !change.libraries_added.is_empty() { - let mut libraries = Vec::clone(&self.db.libraries()); + let mut libraries = Vec::clone(&self.db.library_roots()); for library in change.libraries_added { libraries.push(library.root_id); self.db @@ -65,7 +65,7 @@ impl AnalysisHostImpl { self.apply_root_change(library.root_id, library.root_change); } self.db - .query_mut(ra_db::LibrariesQuery) + .query_mut(ra_db::LibraryRootsQuery) .set((), Arc::new(libraries)); } if let Some(crate_graph) = change.crate_graph { @@ -142,27 +142,26 @@ impl AnalysisImpl { self.db.file_lines(file_id) } pub fn world_symbols(&self, query: Query) -> Cancelable> { + /// Need to wrap Snapshot to provide `Clone` impl for `map_with` + struct Snap(salsa::Snapshot); + impl Clone for Snap { + fn clone(&self) -> Snap { + Snap(self.0.snapshot()) + } + } + let buf: Vec> = if query.libs { + let snap = Snap(self.db.snapshot()); self.db - .libraries() - .iter() - .map(|&lib_id| self.db.library_symbols(lib_id)) + .library_roots() + .par_iter() + .map_with(snap, |db, &lib_id| db.0.library_symbols(lib_id)) .collect() } else { - let files: Vec = self - .db - .source_root(WORKSPACE) - .files - .values() - .map(|&it| it) - .collect(); - - /// Need to wrap Snapshot to provide `Clone` impl for `map_with` - struct Snap(salsa::Snapshot); - impl Clone for Snap { - fn clone(&self) -> Snap { - Snap(self.0.snapshot()) - } + let mut files = Vec::new(); + for &root in self.db.local_roots().iter() { + let sr = self.db.source_root(root); + files.extend(sr.files.values().map(|&it| it)) } let snap = Snap(self.db.snapshot()); diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 300dfc5dd..0db3c3479 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -39,7 +39,7 @@ pub use hir::FnSignatureInfo; pub use ra_db::{ Canceled, Cancelable, FilePosition, - CrateGraph, CrateId, SourceRootId, FileId, WORKSPACE + CrateGraph, CrateId, SourceRootId, FileId }; #[derive(Default)] diff --git a/crates/ra_analysis/src/mock_analysis.rs b/crates/ra_analysis/src/mock_analysis.rs index 691af4a48..0c042e672 100644 --- a/crates/ra_analysis/src/mock_analysis.rs +++ b/crates/ra_analysis/src/mock_analysis.rs @@ -4,7 +4,7 @@ use relative_path::{RelativePathBuf}; use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; use ra_db::mock::FileMap; -use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FilePosition, WORKSPACE}; +use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FilePosition, SourceRootId}; /// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis /// from a set of in-memory files. @@ -78,12 +78,14 @@ impl MockAnalysis { pub fn analysis_host(self) -> AnalysisHost { let mut host = AnalysisHost::default(); let mut file_map = FileMap::default(); + let source_root = SourceRootId(0); let mut change = AnalysisChange::new(); + change.add_root(source_root); for (path, contents) in self.files.into_iter() { assert!(path.starts_with('/')); let path = RelativePathBuf::from_path(&path[1..]).unwrap(); let file_id = file_map.add(path.clone()); - change.add_file(WORKSPACE, file_id, path, Arc::new(contents)); + change.add_file(source_root, file_id, path, Arc::new(contents)); } // change.set_file_resolver(Arc::new(file_map)); host.apply_change(change); diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 51daa8e86..cccf37cc2 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs @@ -8,8 +8,6 @@ use salsa; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct SourceRootId(pub u32); -pub const WORKSPACE: SourceRootId = SourceRootId(0); - #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct FileId(pub u32); @@ -102,8 +100,12 @@ salsa::query_group! { type SourceRootQuery; storage input; } - fn libraries() -> Arc> { - type LibrariesQuery; + fn local_roots() -> Arc> { + type LocalRootsQuery; + storage input; + } + fn library_roots() -> Arc> { + type LibraryRootsQuery; storage input; } fn crate_graph() -> Arc { diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index eeb305b1b..65fa3cbfa 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -24,8 +24,8 @@ impl std::error::Error for Canceled {} pub use crate::{ syntax_ptr::LocalSyntaxPtr, input::{ - FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, WORKSPACE, - FileTextQuery, FileSourceRootQuery, SourceRootQuery, LibrariesQuery, CrateGraphQuery, + FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, + FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery, FileRelativePathQuery }, loc2id::{LocationIntener, NumericId}, -- cgit v1.2.3 From 2fe41574a1695a6608d738f40ec51bc61fc7604a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 16:19:53 +0300 Subject: fix tests --- crates/ra_analysis/src/imp.rs | 15 ++++++++++++--- crates/ra_analysis/src/lib.rs | 6 +++--- crates/ra_analysis/src/mock_analysis.rs | 2 +- crates/ra_hir/src/mock.rs | 13 ++++++++----- crates/ra_lsp_server/src/server_world.rs | 3 ++- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 46169d863..9e441ca79 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -43,10 +43,19 @@ impl AnalysisHostImpl { pub fn apply_change(&mut self, change: AnalysisChange) { log::info!("apply_change {:?}", change); // self.gc_syntax_trees(); - for root_id in change.new_roots { + if !change.new_roots.is_empty() { + let mut local_roots = Vec::clone(&self.db.local_roots()); + for (root_id, is_local) in change.new_roots { + self.db + .query_mut(ra_db::SourceRootQuery) + .set(root_id, Default::default()); + if is_local { + local_roots.push(root_id); + } + } self.db - .query_mut(ra_db::SourceRootQuery) - .set(root_id, Default::default()); + .query_mut(ra_db::LocalRootsQuery) + .set((), Arc::new(local_roots)); } for (root_id, root_change) in change.roots_changed { diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 0db3c3479..a1d462528 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -44,7 +44,7 @@ pub use ra_db::{ #[derive(Default)] pub struct AnalysisChange { - new_roots: Vec, + new_roots: Vec<(SourceRootId, bool)>, roots_changed: FxHashMap, files_changed: Vec<(FileId, Arc)>, libraries_added: Vec, @@ -95,8 +95,8 @@ impl AnalysisChange { pub fn new() -> AnalysisChange { AnalysisChange::default() } - pub fn add_root(&mut self, root_id: SourceRootId) { - self.new_roots.push(root_id); + pub fn add_root(&mut self, root_id: SourceRootId, is_local: bool) { + self.new_roots.push((root_id, is_local)); } pub fn add_file( &mut self, diff --git a/crates/ra_analysis/src/mock_analysis.rs b/crates/ra_analysis/src/mock_analysis.rs index 0c042e672..7cbdfb953 100644 --- a/crates/ra_analysis/src/mock_analysis.rs +++ b/crates/ra_analysis/src/mock_analysis.rs @@ -80,7 +80,7 @@ impl MockAnalysis { let mut file_map = FileMap::default(); let source_root = SourceRootId(0); let mut change = AnalysisChange::new(); - change.add_root(source_root); + change.add_root(source_root, true); for (path, contents) in self.files.into_iter() { assert!(path.starts_with('/')); let path = RelativePathBuf::from_path(&path[1..]).unwrap(); diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 54260101c..9423e6571 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs @@ -2,12 +2,14 @@ use std::sync::Arc; use parking_lot::Mutex; use salsa::{self, Database}; -use ra_db::{LocationIntener, BaseDatabase, FilePosition, FileId, WORKSPACE, CrateGraph, SourceRoot}; +use ra_db::{LocationIntener, BaseDatabase, FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId}; use relative_path::RelativePathBuf; use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; use crate::{db, DefId, DefLoc}; +const WORKSPACE: SourceRootId = SourceRootId(0); + #[derive(Debug)] pub(crate) struct MockDatabase { events: Mutex>>>, @@ -106,11 +108,11 @@ impl Default for MockDatabase { runtime: salsa::Runtime::default(), id_maps: Default::default(), }; - db.query_mut(ra_db::SourceRootQuery) - .set(ra_db::WORKSPACE, Default::default()); db.query_mut(ra_db::CrateGraphQuery) .set((), Default::default()); - db.query_mut(ra_db::LibrariesQuery) + db.query_mut(ra_db::LocalRootsQuery) + .set((), Default::default()); + db.query_mut(ra_db::LibraryRootsQuery) .set((), Default::default()); db } @@ -163,7 +165,8 @@ salsa::database_storage! { fn file_relative_path() for ra_db::FileRelativePathQuery; fn file_source_root() for ra_db::FileSourceRootQuery; fn source_root() for ra_db::SourceRootQuery; - fn libraries() for ra_db::LibrariesQuery; + fn local_roots() for ra_db::LocalRootsQuery; + fn library_roots() for ra_db::LibraryRootsQuery; fn crate_graph() for ra_db::CrateGraphQuery; } impl ra_db::SyntaxDatabase { diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index bdb4c513f..785877c4b 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -48,7 +48,8 @@ impl ServerWorldState { let roots_to_scan = roots.len(); let (mut vfs, roots) = Vfs::new(roots); for r in roots { - change.add_root(SourceRootId(r.0)); + let is_local = vfs.root2path(r).starts_with(&root); + change.add_root(SourceRootId(r.0), is_local); } let mut crate_graph = CrateGraph::default(); -- cgit v1.2.3 From 590bd5f849cf257f499f6c7aa8da3dc4ffc7578f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 19 Dec 2018 18:04:17 +0300 Subject: workaround across-crate resolve bugs --- crates/ra_hir/src/module/nameres.rs | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index 5540b827f..dc05c7112 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs @@ -252,7 +252,8 @@ where let krate = Crate::new(crate_id); for dep in krate.dependencies(self.db) { if let Some(module) = dep.krate.root_module(self.db)? { - self.add_module_item(&mut module_items, dep.name, module.module_id); + let def_id = module.def_id(self.db); + self.add_module_item(&mut module_items, dep.name, def_id); } } }; @@ -294,21 +295,21 @@ where // Populate modules for (name, module_id) in module_id.children(&self.module_tree) { - self.add_module_item(&mut module_items, name, module_id); + let def_loc = DefLoc { + kind: DefKind::Module, + source_root_id: self.source_root, + module_id, + source_item_id: module_id.source(&self.module_tree).0, + }; + let def_id = def_loc.id(self.db); + self.add_module_item(&mut module_items, name, def_id); } self.result.per_module.insert(module_id, module_items); Ok(()) } - fn add_module_item(&self, module_items: &mut ModuleScope, name: SmolStr, module_id: ModuleId) { - let def_loc = DefLoc { - kind: DefKind::Module, - source_root_id: self.source_root, - module_id, - source_item_id: module_id.source(&self.module_tree).0, - }; - let def_id = def_loc.id(self.db); + fn add_module_item(&self, module_items: &mut ModuleScope, name: SmolStr, def_id: DefId) { let resolution = Resolution { def_id: Some(def_id), import: None, @@ -329,7 +330,7 @@ where ImportKind::Named(ptr) => ptr, }; - let mut curr = match import.path.kind { + let mut curr: ModuleId = match import.path.kind { PathKind::Plain | PathKind::Self_ => module_id, PathKind::Super => { match module_id.parent(&self.module_tree) { @@ -357,8 +358,16 @@ where DefLoc { kind: DefKind::Module, module_id, + source_root_id, .. - } => module_id, + } => { + if source_root_id == self.source_root { + module_id + } else { + // FIXME: across crates resolve + return Ok(()); + } + } _ => return Ok(()), } } else { -- cgit v1.2.3 From 2caac99ef3731b39c484a23cdab00af94de7b645 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 20 Dec 2018 00:57:13 +0300 Subject: resolve paths across crates --- crates/ra_hir/src/module/nameres.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index dc05c7112..4161442b2 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs @@ -32,7 +32,7 @@ use crate::{ SourceItemId, SourceFileItemId, SourceFileItems, Path, PathKind, HirDatabase, Crate, - module::{ModuleId, ModuleTree}, + module::{Module, ModuleId, ModuleTree}, }; /// Item map is the result of the name resolution. Item map contains, for each @@ -357,14 +357,27 @@ where curr = match def_id.loc(self.db) { DefLoc { kind: DefKind::Module, - module_id, + module_id: target_module_id, source_root_id, .. } => { if source_root_id == self.source_root { - module_id + target_module_id } else { - // FIXME: across crates resolve + let module = Module::new(self.db, source_root_id, target_module_id)?; + let path = Path { + segments: import.path.segments[i + 1..].iter().cloned().collect(), + kind: PathKind::Crate, + }; + if let Some(def_id) = module.resolve_path(self.db, path)? { + self.update(module_id, |items| { + let res = Resolution { + def_id: Some(def_id), + import: Some(ptr), + }; + items.items.insert(name.clone(), res); + }) + } return Ok(()); } } -- cgit v1.2.3 From 2d4582bfc648fd1a1ce92ea677aeb1c82ee8a631 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 20 Dec 2018 01:00:54 +0300 Subject: fixme comment --- crates/ra_hir/src/module/nameres.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index 4161442b2..f44abc730 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs @@ -37,6 +37,7 @@ use crate::{ /// Item map is the result of the name resolution. Item map contains, for each /// module, the set of visible items. +// FIXME: currenty we compute item map per source-root. We should do it per crate instead. #[derive(Default, Debug, PartialEq, Eq)] pub struct ItemMap { pub per_module: FxHashMap, -- cgit v1.2.3 From 7a6f5164f39f9b66640d3c0778410588add486c8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 20 Dec 2018 11:53:29 +0300 Subject: enable incremental release --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 5cfc064b5..95830561d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,4 +2,5 @@ members = [ "crates/*" ] [profile.release] +incremental = true debug = true -- cgit v1.2.3 From 97812c192a2f650520a6b73f9e3d49919515947d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 20 Dec 2018 12:02:57 +0300 Subject: Restore library symbols --- crates/ra_analysis/src/imp.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 9e441ca79..2d00d23be 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -23,7 +23,7 @@ use hir::{ use crate::{ completion::{completions, CompletionItem}, db, - symbol_index::{SymbolIndex, SymbolsDatabase}, + symbol_index::{SymbolIndex, SymbolsDatabase, LibrarySymbolsQuery}, AnalysisChange, RootChange, Cancelable, CrateId, Diagnostic, FileId, FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit, ReferenceResolution, @@ -71,6 +71,9 @@ impl AnalysisHostImpl { self.db .query_mut(ra_db::SourceRootQuery) .set(library.root_id, Default::default()); + self.db + .query_mut(LibrarySymbolsQuery) + .set(library.root_id, Arc::new(library.symbol_index)); self.apply_root_change(library.root_id, library.root_change); } self.db -- cgit v1.2.3 From 6782fe2a5b84315f66a227b035c6beae7834f0b0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 20 Dec 2018 12:05:29 +0300 Subject: Treat --- crates/ra_analysis/src/imp.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 2d00d23be..4ef2129c3 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -73,8 +73,8 @@ impl AnalysisHostImpl { .set(library.root_id, Default::default()); self.db .query_mut(LibrarySymbolsQuery) - .set(library.root_id, Arc::new(library.symbol_index)); - self.apply_root_change(library.root_id, library.root_change); + .set_constant(library.root_id, Arc::new(library.symbol_index)); + self.apply_root_change_constant(library.root_id, library.root_change); } self.db .query_mut(ra_db::LibraryRootsQuery) @@ -115,6 +115,34 @@ impl AnalysisHostImpl { .set(root_id, Arc::new(source_root)); } + fn apply_root_change_constant(&mut self, root_id: SourceRootId, root_change: RootChange) { + let mut source_root = SourceRoot::clone(&self.db.source_root(root_id)); + for add_file in root_change.added { + self.db + .query_mut(ra_db::FileTextQuery) + .set_constant(add_file.file_id, add_file.text); + self.db + .query_mut(ra_db::FileRelativePathQuery) + .set_constant(add_file.file_id, add_file.path.clone()); + self.db + .query_mut(ra_db::FileSourceRootQuery) + .set_constant(add_file.file_id, root_id); + source_root.files.insert(add_file.path, add_file.file_id); + } + for remove_file in root_change.removed { + self.db + .query_mut(ra_db::FileTextQuery) + .set_constant(remove_file.file_id, Default::default()); + self.db + .query_mut(ra_db::FileRelativePathQuery) + .set_constant(remove_file.file_id, Default::default()); + source_root.files.remove(&remove_file.path); + } + self.db + .query_mut(ra_db::SourceRootQuery) + .set_constant(root_id, Arc::new(source_root)); + } + #[allow(unused)] /// Ideally, we should call this function from time to time to collect heavy /// syntax trees. However, if we actually do that, everything is recomputed -- cgit v1.2.3 From a084412f0698d5f54d586f707930e141c88b0673 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 20 Dec 2018 12:06:23 +0300 Subject: set symbol index as const --- crates/ra_analysis/src/imp.rs | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 4ef2129c3..c4291885a 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -74,7 +74,7 @@ impl AnalysisHostImpl { self.db .query_mut(LibrarySymbolsQuery) .set_constant(library.root_id, Arc::new(library.symbol_index)); - self.apply_root_change_constant(library.root_id, library.root_change); + self.apply_root_change(library.root_id, library.root_change); } self.db .query_mut(ra_db::LibraryRootsQuery) @@ -115,34 +115,6 @@ impl AnalysisHostImpl { .set(root_id, Arc::new(source_root)); } - fn apply_root_change_constant(&mut self, root_id: SourceRootId, root_change: RootChange) { - let mut source_root = SourceRoot::clone(&self.db.source_root(root_id)); - for add_file in root_change.added { - self.db - .query_mut(ra_db::FileTextQuery) - .set_constant(add_file.file_id, add_file.text); - self.db - .query_mut(ra_db::FileRelativePathQuery) - .set_constant(add_file.file_id, add_file.path.clone()); - self.db - .query_mut(ra_db::FileSourceRootQuery) - .set_constant(add_file.file_id, root_id); - source_root.files.insert(add_file.path, add_file.file_id); - } - for remove_file in root_change.removed { - self.db - .query_mut(ra_db::FileTextQuery) - .set_constant(remove_file.file_id, Default::default()); - self.db - .query_mut(ra_db::FileRelativePathQuery) - .set_constant(remove_file.file_id, Default::default()); - source_root.files.remove(&remove_file.path); - } - self.db - .query_mut(ra_db::SourceRootQuery) - .set_constant(root_id, Arc::new(source_root)); - } - #[allow(unused)] /// Ideally, we should call this function from time to time to collect heavy /// syntax trees. However, if we actually do that, everything is recomputed -- cgit v1.2.3