diff options
-rw-r--r-- | Cargo.lock | 10 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_db/src/input.rs | 34 | ||||
-rw-r--r-- | crates/ra_db/src/mock.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/krate.rs | 48 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 48 | ||||
-rw-r--r-- | crates/ra_hir/src/mock.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/module.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/module/nameres.rs | 203 | ||||
-rw-r--r-- | crates/ra_hir/src/module/nameres/tests.rs | 127 | ||||
-rw-r--r-- | crates/ra_hir/src/query_definitions.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 24 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/project_model.rs | 36 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/server_world.rs | 39 | ||||
-rw-r--r-- | editors/code/package-lock.json | 164 | ||||
-rw-r--r-- | editors/code/package.json | 1 |
18 files changed, 475 insertions, 318 deletions
diff --git a/Cargo.lock b/Cargo.lock index 4f46e26fb..1f69a91b2 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -697,6 +697,7 @@ dependencies = [ | |||
697 | "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", | 697 | "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |
698 | "test_utils 0.1.0", | 698 | "test_utils 0.1.0", |
699 | "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | 699 | "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |
700 | "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
700 | "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | 701 | "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |
701 | "walkdir 2.2.6 (registry+https://github.com/rust-lang/crates.io-index)", | 702 | "walkdir 2.2.6 (registry+https://github.com/rust-lang/crates.io-index)", |
702 | ] | 703 | ] |
@@ -1104,6 +1105,14 @@ dependencies = [ | |||
1104 | ] | 1105 | ] |
1105 | 1106 | ||
1106 | [[package]] | 1107 | [[package]] |
1108 | name = "threadpool" | ||
1109 | version = "1.7.1" | ||
1110 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1111 | dependencies = [ | ||
1112 | "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1113 | ] | ||
1114 | |||
1115 | [[package]] | ||
1107 | name = "time" | 1116 | name = "time" |
1108 | version = "0.1.40" | 1117 | version = "0.1.40" |
1109 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1118 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1414,6 +1423,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1414 | "checksum text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8009d7bdbd896a7e09b595f8f9325a19047fc708653e60d0895202b82135048f" | 1423 | "checksum text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8009d7bdbd896a7e09b595f8f9325a19047fc708653e60d0895202b82135048f" |
1415 | "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" | 1424 | "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" |
1416 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" | 1425 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" |
1426 | "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" | ||
1417 | "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" | 1427 | "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" |
1418 | "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" | 1428 | "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" |
1419 | "checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77" | 1429 | "checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77" |
diff --git a/Cargo.toml b/Cargo.toml index 8e4e84729..5cfc064b5 100644 --- a/Cargo.toml +++ b/Cargo.toml | |||
@@ -1,6 +1,5 @@ | |||
1 | [workspace] | 1 | [workspace] |
2 | members = [ "crates/*" ] | 2 | members = [ "crates/*" ] |
3 | exclude = [ "crates/rowan"] | ||
4 | 3 | ||
5 | [profile.release] | 4 | [profile.release] |
6 | debug = true | 5 | debug = true |
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index 7d9faa43c..ac144b991 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use rustc_hash::FxHashMap; | 3 | use rustc_hash::{FxHashSet, FxHashMap}; |
4 | use rustc_hash::FxHashSet; | 4 | use ra_syntax::SmolStr; |
5 | use salsa; | 5 | use salsa; |
6 | 6 | ||
7 | use crate::file_resolver::FileResolverImp; | 7 | use crate::file_resolver::FileResolverImp; |
@@ -20,25 +20,32 @@ pub struct CrateGraph { | |||
20 | #[derive(Debug, Clone, PartialEq, Eq)] | 20 | #[derive(Debug, Clone, PartialEq, Eq)] |
21 | struct CrateData { | 21 | struct CrateData { |
22 | file_id: FileId, | 22 | file_id: FileId, |
23 | deps: Vec<Dependency>, | 23 | dependencies: Vec<Dependency>, |
24 | } | 24 | } |
25 | 25 | ||
26 | impl CrateData { | 26 | impl CrateData { |
27 | fn new(file_id: FileId) -> CrateData { | 27 | fn new(file_id: FileId) -> CrateData { |
28 | CrateData { | 28 | CrateData { |
29 | file_id, | 29 | file_id, |
30 | deps: Vec::new(), | 30 | dependencies: Vec::new(), |
31 | } | 31 | } |
32 | } | 32 | } |
33 | 33 | ||
34 | fn add_dep(&mut self, dep: CrateId) { | 34 | fn add_dep(&mut self, name: SmolStr, crate_id: CrateId) { |
35 | self.deps.push(Dependency { crate_: dep }) | 35 | self.dependencies.push(Dependency { name, crate_id }) |
36 | } | 36 | } |
37 | } | 37 | } |
38 | 38 | ||
39 | #[derive(Debug, Clone, PartialEq, Eq)] | 39 | #[derive(Debug, Clone, PartialEq, Eq)] |
40 | pub struct Dependency { | 40 | pub struct Dependency { |
41 | crate_: CrateId, | 41 | pub crate_id: CrateId, |
42 | pub name: SmolStr, | ||
43 | } | ||
44 | |||
45 | impl Dependency { | ||
46 | pub fn crate_id(&self) -> CrateId { | ||
47 | self.crate_id | ||
48 | } | ||
42 | } | 49 | } |
43 | 50 | ||
44 | impl CrateGraph { | 51 | impl CrateGraph { |
@@ -48,8 +55,11 @@ impl CrateGraph { | |||
48 | assert!(prev.is_none()); | 55 | assert!(prev.is_none()); |
49 | crate_id | 56 | crate_id |
50 | } | 57 | } |
51 | pub fn add_dep(&mut self, from: CrateId, to: CrateId) { | 58 | //FIXME: check that we don't have cycles here. |
52 | self.arena.get_mut(&from).unwrap().add_dep(to) | 59 | // Just a simple depth first search from `to` should work, |
60 | // the graph is small. | ||
61 | pub fn add_dep(&mut self, from: CrateId, name: SmolStr, to: CrateId) { | ||
62 | self.arena.get_mut(&from).unwrap().add_dep(name, to) | ||
53 | } | 63 | } |
54 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { | 64 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { |
55 | self.arena[&crate_id].file_id | 65 | self.arena[&crate_id].file_id |
@@ -61,6 +71,12 @@ impl CrateGraph { | |||
61 | .find(|(_crate_id, data)| data.file_id == file_id)?; | 71 | .find(|(_crate_id, data)| data.file_id == file_id)?; |
62 | Some(crate_id) | 72 | Some(crate_id) |
63 | } | 73 | } |
74 | pub fn dependencies<'a>( | ||
75 | &'a self, | ||
76 | crate_id: CrateId, | ||
77 | ) -> impl Iterator<Item = &'a Dependency> + 'a { | ||
78 | self.arena[&crate_id].dependencies.iter() | ||
79 | } | ||
64 | } | 80 | } |
65 | 81 | ||
66 | salsa::query_group! { | 82 | salsa::query_group! { |
diff --git a/crates/ra_db/src/mock.rs b/crates/ra_db/src/mock.rs index 2840f9655..2f7551597 100644 --- a/crates/ra_db/src/mock.rs +++ b/crates/ra_db/src/mock.rs | |||
@@ -5,7 +5,7 @@ use relative_path::{RelativePath, RelativePathBuf}; | |||
5 | 5 | ||
6 | use crate::{FileId, FileResolver, SourceRoot, FileResolverImp}; | 6 | use crate::{FileId, FileResolver, SourceRoot, FileResolverImp}; |
7 | 7 | ||
8 | #[derive(Default, Debug)] | 8 | #[derive(Default, Debug, Clone)] |
9 | pub struct FileMap(Vec<(FileId, RelativePathBuf)>); | 9 | pub struct FileMap(Vec<(FileId, RelativePathBuf)>); |
10 | 10 | ||
11 | impl FileMap { | 11 | impl FileMap { |
@@ -28,6 +28,11 @@ impl FileMap { | |||
28 | self.iter().map(|(id, _)| id).collect() | 28 | self.iter().map(|(id, _)| id).collect() |
29 | } | 29 | } |
30 | 30 | ||
31 | pub fn file_id(&self, path: &str) -> FileId { | ||
32 | assert!(path.starts_with('/')); | ||
33 | self.iter().find(|(_, p)| p == &path[1..]).unwrap().0 | ||
34 | } | ||
35 | |||
31 | fn iter<'a>(&'a self) -> impl Iterator<Item = (FileId, &'a RelativePath)> + 'a { | 36 | fn iter<'a>(&'a self) -> impl Iterator<Item = (FileId, &'a RelativePath)> + 'a { |
32 | self.0 | 37 | self.0 |
33 | .iter() | 38 | .iter() |
diff --git a/crates/ra_hir/src/krate.rs b/crates/ra_hir/src/krate.rs new file mode 100644 index 000000000..1196dcef1 --- /dev/null +++ b/crates/ra_hir/src/krate.rs | |||
@@ -0,0 +1,48 @@ | |||
1 | use ra_syntax::SmolStr; | ||
2 | pub use ra_db::CrateId; | ||
3 | |||
4 | use crate::{HirDatabase, Module, Cancelable}; | ||
5 | |||
6 | /// hir::Crate describes a single crate. It's the main inteface with which | ||
7 | /// crate's dependencies interact. Mostly, it should be just a proxy for the | ||
8 | /// root module. | ||
9 | #[derive(Debug)] | ||
10 | pub struct Crate { | ||
11 | crate_id: CrateId, | ||
12 | } | ||
13 | |||
14 | #[derive(Debug)] | ||
15 | pub struct CrateDependency { | ||
16 | pub krate: Crate, | ||
17 | pub name: SmolStr, | ||
18 | } | ||
19 | |||
20 | impl Crate { | ||
21 | pub(crate) fn new(crate_id: CrateId) -> Crate { | ||
22 | Crate { crate_id } | ||
23 | } | ||
24 | pub fn dependencies(&self, db: &impl HirDatabase) -> Vec<CrateDependency> { | ||
25 | let crate_graph = db.crate_graph(); | ||
26 | crate_graph | ||
27 | .dependencies(self.crate_id) | ||
28 | .map(|dep| { | ||
29 | let krate = Crate::new(dep.crate_id()); | ||
30 | let name = dep.name.clone(); | ||
31 | CrateDependency { krate, name } | ||
32 | }) | ||
33 | .collect() | ||
34 | } | ||
35 | pub fn root_module(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { | ||
36 | let crate_graph = db.crate_graph(); | ||
37 | let file_id = crate_graph.crate_root(self.crate_id); | ||
38 | let source_root_id = db.file_source_root(file_id); | ||
39 | let module_tree = db.module_tree(source_root_id)?; | ||
40 | // FIXME: teach module tree about crate roots instead of guessing | ||
41 | let (module_id, _) = ctry!(module_tree | ||
42 | .modules_with_sources() | ||
43 | .find(|(_, src)| src.file_id() == file_id)); | ||
44 | |||
45 | let module = Module::new(db, source_root_id, module_id)?; | ||
46 | Ok(Some(module)) | ||
47 | } | ||
48 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 983ce99cb..760524f6b 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -18,12 +18,14 @@ pub mod db; | |||
18 | #[cfg(test)] | 18 | #[cfg(test)] |
19 | mod mock; | 19 | mod mock; |
20 | mod query_definitions; | 20 | mod query_definitions; |
21 | mod function; | ||
22 | mod module; | ||
23 | mod path; | 21 | mod path; |
24 | mod arena; | 22 | mod arena; |
25 | pub mod source_binder; | 23 | pub mod source_binder; |
26 | 24 | ||
25 | mod krate; | ||
26 | mod module; | ||
27 | mod function; | ||
28 | |||
27 | use std::ops::Index; | 29 | use std::ops::Index; |
28 | 30 | ||
29 | use ra_syntax::{SyntaxNodeRef, SyntaxNode}; | 31 | use ra_syntax::{SyntaxNodeRef, SyntaxNode}; |
@@ -36,6 +38,7 @@ use crate::{ | |||
36 | 38 | ||
37 | pub use self::{ | 39 | pub use self::{ |
38 | path::{Path, PathKind}, | 40 | path::{Path, PathKind}, |
41 | krate::Crate, | ||
39 | module::{Module, ModuleId, Problem, nameres::ItemMap}, | 42 | module::{Module, ModuleId, Problem, nameres::ItemMap}, |
40 | function::{Function, FnScopes}, | 43 | function::{Function, FnScopes}, |
41 | }; | 44 | }; |
@@ -110,22 +113,47 @@ pub struct SourceItemId { | |||
110 | } | 113 | } |
111 | 114 | ||
112 | /// Maps item's `SyntaxNode`s to `SourceFileItemId` and back. | 115 | /// Maps item's `SyntaxNode`s to `SourceFileItemId` and back. |
113 | #[derive(Debug, PartialEq, Eq, Default)] | 116 | #[derive(Debug, PartialEq, Eq)] |
114 | pub struct SourceFileItems { | 117 | pub struct SourceFileItems { |
118 | file_id: FileId, | ||
115 | arena: Arena<SyntaxNode>, | 119 | arena: Arena<SyntaxNode>, |
116 | } | 120 | } |
117 | 121 | ||
118 | impl SourceFileItems { | 122 | impl SourceFileItems { |
123 | fn new(file_id: FileId) -> SourceFileItems { | ||
124 | SourceFileItems { | ||
125 | file_id, | ||
126 | arena: Arena::default(), | ||
127 | } | ||
128 | } | ||
129 | |||
119 | fn alloc(&mut self, item: SyntaxNode) -> SourceFileItemId { | 130 | fn alloc(&mut self, item: SyntaxNode) -> SourceFileItemId { |
120 | self.arena.alloc(item) | 131 | self.arena.alloc(item) |
121 | } | 132 | } |
122 | pub fn id_of(&self, item: SyntaxNodeRef) -> SourceFileItemId { | 133 | pub fn id_of(&self, file_id: FileId, item: SyntaxNodeRef) -> SourceFileItemId { |
123 | let (id, _item) = self | 134 | assert_eq!( |
124 | .arena | 135 | self.file_id, file_id, |
125 | .iter() | 136 | "SourceFileItems: wrong file, expected {:?}, got {:?}", |
126 | .find(|(_id, i)| i.borrowed() == item) | 137 | self.file_id, file_id |
127 | .unwrap(); | 138 | ); |
128 | id | 139 | self.id_of_unchecked(item) |
140 | } | ||
141 | fn id_of_unchecked(&self, item: SyntaxNodeRef) -> SourceFileItemId { | ||
142 | if let Some((id, _)) = self.arena.iter().find(|(_id, i)| i.borrowed() == item) { | ||
143 | return id; | ||
144 | } | ||
145 | // This should not happen. Let's try to give a sensible diagnostics. | ||
146 | if let Some((_, i)) = self.arena.iter().find(|(_id, i)| i.range() == item.range()) { | ||
147 | panic!( | ||
148 | "unequal syntax nodes with the same range:\n{:?}\n{:?}", | ||
149 | item, i | ||
150 | ) | ||
151 | } | ||
152 | panic!( | ||
153 | "Can't find {:?} in SourceFileItems:\n{:?}", | ||
154 | item, | ||
155 | self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), | ||
156 | ); | ||
129 | } | 157 | } |
130 | pub fn id_of_source_file(&self) -> SourceFileItemId { | 158 | pub fn id_of_source_file(&self) -> SourceFileItemId { |
131 | let (id, _syntax) = self.arena.iter().next().unwrap(); | 159 | let (id, _syntax) = self.arena.iter().next().unwrap(); |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index e855df11d..b7193c4f3 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -2,7 +2,7 @@ use std::sync::Arc; | |||
2 | 2 | ||
3 | use parking_lot::Mutex; | 3 | use parking_lot::Mutex; |
4 | use salsa::{self, Database}; | 4 | use salsa::{self, Database}; |
5 | use ra_db::{LocationIntener, BaseDatabase, FilePosition, mock::FileMap, FileId, WORKSPACE}; | 5 | use ra_db::{LocationIntener, BaseDatabase, FilePosition, mock::FileMap, FileId, WORKSPACE, CrateGraph}; |
6 | use relative_path::RelativePathBuf; | 6 | use relative_path::RelativePathBuf; |
7 | use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; | 7 | use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; |
8 | 8 | ||
@@ -16,7 +16,24 @@ pub(crate) struct MockDatabase { | |||
16 | } | 16 | } |
17 | 17 | ||
18 | impl MockDatabase { | 18 | impl MockDatabase { |
19 | pub(crate) fn with_files(fixture: &str) -> (MockDatabase, FileMap) { | ||
20 | let (db, file_map, position) = MockDatabase::from_fixture(fixture); | ||
21 | assert!(position.is_none()); | ||
22 | (db, file_map) | ||
23 | } | ||
24 | |||
19 | pub(crate) fn with_position(fixture: &str) -> (MockDatabase, FilePosition) { | 25 | pub(crate) fn with_position(fixture: &str) -> (MockDatabase, FilePosition) { |
26 | let (db, _, position) = MockDatabase::from_fixture(fixture); | ||
27 | let position = position.expect("expected a marker ( <|> )"); | ||
28 | (db, position) | ||
29 | } | ||
30 | |||
31 | pub(crate) fn set_crate_graph(&mut self, crate_graph: CrateGraph) { | ||
32 | self.query_mut(ra_db::CrateGraphQuery) | ||
33 | .set((), Arc::new(crate_graph)); | ||
34 | } | ||
35 | |||
36 | fn from_fixture(fixture: &str) -> (MockDatabase, FileMap, Option<FilePosition>) { | ||
20 | let mut db = MockDatabase::default(); | 37 | let mut db = MockDatabase::default(); |
21 | 38 | ||
22 | let mut position = None; | 39 | let mut position = None; |
@@ -32,11 +49,10 @@ impl MockDatabase { | |||
32 | db.add_file(&mut file_map, &entry.meta, &entry.text); | 49 | db.add_file(&mut file_map, &entry.meta, &entry.text); |
33 | } | 50 | } |
34 | } | 51 | } |
35 | let position = position.expect("expected a marker (<|>)"); | 52 | let source_root = file_map.clone().into_source_root(); |
36 | let source_root = file_map.into_source_root(); | ||
37 | db.query_mut(ra_db::SourceRootQuery) | 53 | db.query_mut(ra_db::SourceRootQuery) |
38 | .set(WORKSPACE, Arc::new(source_root)); | 54 | .set(WORKSPACE, Arc::new(source_root)); |
39 | (db, position) | 55 | (db, file_map, position) |
40 | } | 56 | } |
41 | 57 | ||
42 | fn add_file(&mut self, file_map: &mut FileMap, path: &str, text: &str) -> FileId { | 58 | fn add_file(&mut self, file_map: &mut FileMap, path: &str, text: &str) -> FileId { |
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs index 580c737c3..c6bb76d56 100644 --- a/crates/ra_hir/src/module.rs +++ b/crates/ra_hir/src/module.rs | |||
@@ -12,7 +12,7 @@ use ra_db::{SourceRootId, FileId, Cancelable}; | |||
12 | use relative_path::RelativePathBuf; | 12 | use relative_path::RelativePathBuf; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | DefKind, DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, | 15 | DefKind, DefLoc, DefId, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate, |
16 | arena::{Arena, Id}, | 16 | arena::{Arena, Id}, |
17 | }; | 17 | }; |
18 | 18 | ||
@@ -64,6 +64,15 @@ impl Module { | |||
64 | }) | 64 | }) |
65 | } | 65 | } |
66 | 66 | ||
67 | /// Returns the crate this module is part of. | ||
68 | pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { | ||
69 | let root_id = self.module_id.crate_root(&self.tree); | ||
70 | let file_id = root_id.source(&self.tree).file_id(); | ||
71 | let crate_graph = db.crate_graph(); | ||
72 | let crate_id = crate_graph.crate_id_for_crate_root(file_id)?; | ||
73 | Some(Crate::new(crate_id)) | ||
74 | } | ||
75 | |||
67 | /// The root of the tree this module is part of | 76 | /// The root of the tree this module is part of |
68 | pub fn crate_root(&self) -> Module { | 77 | pub fn crate_root(&self) -> Module { |
69 | let root_id = self.module_id.crate_root(&self.tree); | 78 | let root_id = self.module_id.crate_root(&self.tree); |
@@ -280,7 +289,7 @@ impl ModuleSource { | |||
280 | ) -> ModuleSource { | 289 | ) -> ModuleSource { |
281 | assert!(!m.has_semi()); | 290 | assert!(!m.has_semi()); |
282 | let file_items = db.file_items(file_id); | 291 | let file_items = db.file_items(file_id); |
283 | let item_id = file_items.id_of(m.syntax()); | 292 | let item_id = file_items.id_of(file_id, m.syntax()); |
284 | ModuleSource::new(file_id, item_id) | 293 | ModuleSource::new(file_id, item_id) |
285 | } | 294 | } |
286 | 295 | ||
diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index 61a1acfe6..9afeade9e 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs | |||
@@ -31,7 +31,7 @@ use crate::{ | |||
31 | DefId, DefLoc, DefKind, | 31 | DefId, DefLoc, DefKind, |
32 | SourceItemId, SourceFileItemId, SourceFileItems, | 32 | SourceItemId, SourceFileItemId, SourceFileItems, |
33 | Path, PathKind, | 33 | Path, PathKind, |
34 | HirDatabase, | 34 | HirDatabase, Crate, |
35 | module::{ModuleId, ModuleTree}, | 35 | module::{ModuleId, ModuleTree}, |
36 | }; | 36 | }; |
37 | 37 | ||
@@ -168,7 +168,7 @@ impl InputModuleItems { | |||
168 | } | 168 | } |
169 | 169 | ||
170 | fn add_use_item(&mut self, file_items: &SourceFileItems, item: ast::UseItem) { | 170 | fn add_use_item(&mut self, file_items: &SourceFileItems, item: ast::UseItem) { |
171 | let file_item_id = file_items.id_of(item.syntax()); | 171 | let file_item_id = file_items.id_of_unchecked(item.syntax()); |
172 | let start_offset = item.syntax().range().start(); | 172 | let start_offset = item.syntax().range().start(); |
173 | Path::expand_use_item(item, |path, range| { | 173 | Path::expand_use_item(item, |path, range| { |
174 | let kind = match range { | 174 | let kind = match range { |
@@ -188,7 +188,7 @@ impl ModuleItem { | |||
188 | let name = item.name()?.text(); | 188 | let name = item.name()?.text(); |
189 | let kind = item.syntax().kind(); | 189 | let kind = item.syntax().kind(); |
190 | let vis = Vis::Other; | 190 | let vis = Vis::Other; |
191 | let id = file_items.id_of(item.syntax()); | 191 | let id = file_items.id_of_unchecked(item.syntax()); |
192 | let res = ModuleItem { | 192 | let res = ModuleItem { |
193 | id, | 193 | id, |
194 | name, | 194 | name, |
@@ -200,34 +200,63 @@ impl ModuleItem { | |||
200 | } | 200 | } |
201 | 201 | ||
202 | pub(crate) struct Resolver<'a, DB> { | 202 | pub(crate) struct Resolver<'a, DB> { |
203 | pub(crate) db: &'a DB, | 203 | db: &'a DB, |
204 | pub(crate) input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>, | 204 | input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>, |
205 | pub(crate) source_root: SourceRootId, | 205 | source_root: SourceRootId, |
206 | pub(crate) module_tree: Arc<ModuleTree>, | 206 | module_tree: Arc<ModuleTree>, |
207 | pub(crate) result: ItemMap, | 207 | result: ItemMap, |
208 | } | 208 | } |
209 | 209 | ||
210 | impl<'a, DB> Resolver<'a, DB> | 210 | impl<'a, DB> Resolver<'a, DB> |
211 | where | 211 | where |
212 | DB: HirDatabase, | 212 | DB: HirDatabase, |
213 | { | 213 | { |
214 | pub(crate) fn new( | ||
215 | db: &'a DB, | ||
216 | input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>, | ||
217 | source_root: SourceRootId, | ||
218 | module_tree: Arc<ModuleTree>, | ||
219 | ) -> Resolver<'a, DB> { | ||
220 | Resolver { | ||
221 | db, | ||
222 | input, | ||
223 | source_root, | ||
224 | module_tree, | ||
225 | result: ItemMap::default(), | ||
226 | } | ||
227 | } | ||
228 | |||
214 | pub(crate) fn resolve(mut self) -> Cancelable<ItemMap> { | 229 | pub(crate) fn resolve(mut self) -> Cancelable<ItemMap> { |
215 | for (&module_id, items) in self.input.iter() { | 230 | for (&module_id, items) in self.input.iter() { |
216 | self.populate_module(module_id, items) | 231 | self.populate_module(module_id, items)?; |
217 | } | 232 | } |
218 | 233 | ||
219 | for &module_id in self.input.keys() { | 234 | for &module_id in self.input.keys() { |
220 | self.db.check_canceled()?; | 235 | self.db.check_canceled()?; |
221 | self.resolve_imports(module_id); | 236 | self.resolve_imports(module_id)?; |
222 | } | 237 | } |
223 | Ok(self.result) | 238 | Ok(self.result) |
224 | } | 239 | } |
225 | 240 | ||
226 | fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) { | 241 | fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) -> Cancelable<()> { |
227 | let file_id = module_id.source(&self.module_tree).file_id(); | 242 | let file_id = module_id.source(&self.module_tree).file_id(); |
228 | 243 | ||
229 | let mut module_items = ModuleScope::default(); | 244 | let mut module_items = ModuleScope::default(); |
230 | 245 | ||
246 | // Populate extern crates prelude | ||
247 | { | ||
248 | let root_id = module_id.crate_root(&self.module_tree); | ||
249 | let file_id = root_id.source(&self.module_tree).file_id(); | ||
250 | let crate_graph = self.db.crate_graph(); | ||
251 | if let Some(crate_id) = crate_graph.crate_id_for_crate_root(file_id) { | ||
252 | let krate = Crate::new(crate_id); | ||
253 | for dep in krate.dependencies(self.db) { | ||
254 | if let Some(module) = dep.krate.root_module(self.db)? { | ||
255 | self.add_module_item(&mut module_items, dep.name, module.module_id); | ||
256 | } | ||
257 | } | ||
258 | }; | ||
259 | } | ||
231 | for import in input.imports.iter() { | 260 | for import in input.imports.iter() { |
232 | if let Some(name) = import.path.segments.iter().last() { | 261 | if let Some(name) = import.path.segments.iter().last() { |
233 | if let ImportKind::Named(import) = import.kind { | 262 | if let ImportKind::Named(import) = import.kind { |
@@ -241,10 +270,9 @@ where | |||
241 | } | 270 | } |
242 | } | 271 | } |
243 | } | 272 | } |
244 | 273 | // Populate explicitelly declared items, except modules | |
245 | for item in input.items.iter() { | 274 | for item in input.items.iter() { |
246 | if item.kind == MODULE { | 275 | if item.kind == MODULE { |
247 | // handle submodules separatelly | ||
248 | continue; | 276 | continue; |
249 | } | 277 | } |
250 | let def_loc = DefLoc { | 278 | let def_loc = DefLoc { |
@@ -264,45 +292,50 @@ where | |||
264 | module_items.items.insert(item.name.clone(), resolution); | 292 | module_items.items.insert(item.name.clone(), resolution); |
265 | } | 293 | } |
266 | 294 | ||
295 | // Populate modules | ||
267 | for (name, module_id) in module_id.children(&self.module_tree) { | 296 | for (name, module_id) in module_id.children(&self.module_tree) { |
268 | let def_loc = DefLoc { | 297 | self.add_module_item(&mut module_items, name, module_id); |
269 | kind: DefKind::Module, | ||
270 | source_root_id: self.source_root, | ||
271 | module_id, | ||
272 | source_item_id: module_id.source(&self.module_tree).0, | ||
273 | }; | ||
274 | let def_id = def_loc.id(self.db); | ||
275 | let resolution = Resolution { | ||
276 | def_id: Some(def_id), | ||
277 | import: None, | ||
278 | }; | ||
279 | module_items.items.insert(name, resolution); | ||
280 | } | 298 | } |
281 | 299 | ||
282 | self.result.per_module.insert(module_id, module_items); | 300 | self.result.per_module.insert(module_id, module_items); |
301 | Ok(()) | ||
283 | } | 302 | } |
284 | 303 | ||
285 | fn resolve_imports(&mut self, module_id: ModuleId) { | 304 | fn add_module_item(&self, module_items: &mut ModuleScope, name: SmolStr, module_id: ModuleId) { |
305 | let def_loc = DefLoc { | ||
306 | kind: DefKind::Module, | ||
307 | source_root_id: self.source_root, | ||
308 | module_id, | ||
309 | source_item_id: module_id.source(&self.module_tree).0, | ||
310 | }; | ||
311 | let def_id = def_loc.id(self.db); | ||
312 | let resolution = Resolution { | ||
313 | def_id: Some(def_id), | ||
314 | import: None, | ||
315 | }; | ||
316 | module_items.items.insert(name, resolution); | ||
317 | } | ||
318 | |||
319 | fn resolve_imports(&mut self, module_id: ModuleId) -> Cancelable<()> { | ||
286 | for import in self.input[&module_id].imports.iter() { | 320 | for import in self.input[&module_id].imports.iter() { |
287 | self.resolve_import(module_id, import); | 321 | self.resolve_import(module_id, import)?; |
288 | } | 322 | } |
323 | Ok(()) | ||
289 | } | 324 | } |
290 | 325 | ||
291 | fn resolve_import(&mut self, module_id: ModuleId, import: &Import) { | 326 | fn resolve_import(&mut self, module_id: ModuleId, import: &Import) -> Cancelable<()> { |
292 | let ptr = match import.kind { | 327 | let ptr = match import.kind { |
293 | ImportKind::Glob => return, | 328 | ImportKind::Glob => return Ok(()), |
294 | ImportKind::Named(ptr) => ptr, | 329 | ImportKind::Named(ptr) => ptr, |
295 | }; | 330 | }; |
296 | 331 | ||
297 | let mut curr = match import.path.kind { | 332 | let mut curr = match import.path.kind { |
298 | // TODO: handle extern crates | 333 | PathKind::Plain | PathKind::Self_ => module_id, |
299 | PathKind::Plain => return, | ||
300 | PathKind::Self_ => module_id, | ||
301 | PathKind::Super => { | 334 | PathKind::Super => { |
302 | match module_id.parent(&self.module_tree) { | 335 | match module_id.parent(&self.module_tree) { |
303 | Some(it) => it, | 336 | Some(it) => it, |
304 | // TODO: error | 337 | // TODO: error |
305 | None => return, | 338 | None => return Ok(()), |
306 | } | 339 | } |
307 | } | 340 | } |
308 | PathKind::Crate => module_id.crate_root(&self.module_tree), | 341 | PathKind::Crate => module_id.crate_root(&self.module_tree), |
@@ -312,10 +345,10 @@ where | |||
312 | let is_last = i == import.path.segments.len() - 1; | 345 | let is_last = i == import.path.segments.len() - 1; |
313 | 346 | ||
314 | let def_id = match self.result.per_module[&curr].items.get(name) { | 347 | let def_id = match self.result.per_module[&curr].items.get(name) { |
315 | None => return, | 348 | None => return Ok(()), |
316 | Some(res) => match res.def_id { | 349 | Some(res) => match res.def_id { |
317 | Some(it) => it, | 350 | Some(it) => it, |
318 | None => return, | 351 | None => return Ok(()), |
319 | }, | 352 | }, |
320 | }; | 353 | }; |
321 | 354 | ||
@@ -326,7 +359,7 @@ where | |||
326 | module_id, | 359 | module_id, |
327 | .. | 360 | .. |
328 | } => module_id, | 361 | } => module_id, |
329 | _ => return, | 362 | _ => return Ok(()), |
330 | } | 363 | } |
331 | } else { | 364 | } else { |
332 | self.update(module_id, |items| { | 365 | self.update(module_id, |items| { |
@@ -338,6 +371,7 @@ where | |||
338 | }) | 371 | }) |
339 | } | 372 | } |
340 | } | 373 | } |
374 | Ok(()) | ||
341 | } | 375 | } |
342 | 376 | ||
343 | fn update(&mut self, module_id: ModuleId, f: impl FnOnce(&mut ModuleScope)) { | 377 | fn update(&mut self, module_id: ModuleId, f: impl FnOnce(&mut ModuleScope)) { |
@@ -347,99 +381,4 @@ where | |||
347 | } | 381 | } |
348 | 382 | ||
349 | #[cfg(test)] | 383 | #[cfg(test)] |
350 | mod tests { | 384 | mod tests; |
351 | use std::sync::Arc; | ||
352 | |||
353 | use salsa::Database; | ||
354 | use ra_db::FilesDatabase; | ||
355 | use ra_syntax::SmolStr; | ||
356 | |||
357 | use crate::{ | ||
358 | self as hir, | ||
359 | db::HirDatabase, | ||
360 | mock::MockDatabase, | ||
361 | }; | ||
362 | |||
363 | fn item_map(fixture: &str) -> (Arc<hir::ItemMap>, hir::ModuleId) { | ||
364 | let (db, pos) = MockDatabase::with_position(fixture); | ||
365 | let source_root = db.file_source_root(pos.file_id); | ||
366 | let module = hir::source_binder::module_from_position(&db, pos) | ||
367 | .unwrap() | ||
368 | .unwrap(); | ||
369 | let module_id = module.module_id; | ||
370 | (db.item_map(source_root).unwrap(), module_id) | ||
371 | } | ||
372 | |||
373 | #[test] | ||
374 | fn test_item_map() { | ||
375 | let (item_map, module_id) = item_map( | ||
376 | " | ||
377 | //- /lib.rs | ||
378 | mod foo; | ||
379 | |||
380 | use crate::foo::bar::Baz; | ||
381 | <|> | ||
382 | |||
383 | //- /foo/mod.rs | ||
384 | pub mod bar; | ||
385 | |||
386 | //- /foo/bar.rs | ||
387 | pub struct Baz; | ||
388 | ", | ||
389 | ); | ||
390 | let name = SmolStr::from("Baz"); | ||
391 | let resolution = &item_map.per_module[&module_id].items[&name]; | ||
392 | assert!(resolution.def_id.is_some()); | ||
393 | } | ||
394 | |||
395 | #[test] | ||
396 | fn typing_inside_a_function_should_not_invalidate_item_map() { | ||
397 | let (mut db, pos) = MockDatabase::with_position( | ||
398 | " | ||
399 | //- /lib.rs | ||
400 | mod foo;<|> | ||
401 | |||
402 | use crate::foo::bar::Baz; | ||
403 | |||
404 | fn foo() -> i32 { | ||
405 | 1 + 1 | ||
406 | } | ||
407 | //- /foo/mod.rs | ||
408 | pub mod bar; | ||
409 | |||
410 | //- /foo/bar.rs | ||
411 | pub struct Baz; | ||
412 | ", | ||
413 | ); | ||
414 | let source_root = db.file_source_root(pos.file_id); | ||
415 | { | ||
416 | let events = db.log_executed(|| { | ||
417 | db.item_map(source_root).unwrap(); | ||
418 | }); | ||
419 | assert!(format!("{:?}", events).contains("item_map")) | ||
420 | } | ||
421 | |||
422 | let new_text = " | ||
423 | mod foo; | ||
424 | |||
425 | use crate::foo::bar::Baz; | ||
426 | |||
427 | fn foo() -> i32 { 92 } | ||
428 | " | ||
429 | .to_string(); | ||
430 | |||
431 | db.query_mut(ra_db::FileTextQuery) | ||
432 | .set(pos.file_id, Arc::new(new_text)); | ||
433 | |||
434 | { | ||
435 | let events = db.log_executed(|| { | ||
436 | db.item_map(source_root).unwrap(); | ||
437 | }); | ||
438 | assert!( | ||
439 | !format!("{:?}", events).contains("_item_map"), | ||
440 | "{:#?}", | ||
441 | events | ||
442 | ) | ||
443 | } | ||
444 | } | ||
445 | } | ||
diff --git a/crates/ra_hir/src/module/nameres/tests.rs b/crates/ra_hir/src/module/nameres/tests.rs new file mode 100644 index 000000000..9ddc32dcd --- /dev/null +++ b/crates/ra_hir/src/module/nameres/tests.rs | |||
@@ -0,0 +1,127 @@ | |||
1 | use std::sync::Arc; | ||
2 | |||
3 | use salsa::Database; | ||
4 | use ra_db::{FilesDatabase, CrateGraph}; | ||
5 | use ra_syntax::SmolStr; | ||
6 | |||
7 | use crate::{ | ||
8 | self as hir, | ||
9 | db::HirDatabase, | ||
10 | mock::MockDatabase, | ||
11 | }; | ||
12 | |||
13 | fn item_map(fixture: &str) -> (Arc<hir::ItemMap>, hir::ModuleId) { | ||
14 | let (db, pos) = MockDatabase::with_position(fixture); | ||
15 | let source_root = db.file_source_root(pos.file_id); | ||
16 | let module = hir::source_binder::module_from_position(&db, pos) | ||
17 | .unwrap() | ||
18 | .unwrap(); | ||
19 | let module_id = module.module_id; | ||
20 | (db.item_map(source_root).unwrap(), module_id) | ||
21 | } | ||
22 | |||
23 | #[test] | ||
24 | fn item_map_smoke_test() { | ||
25 | let (item_map, module_id) = item_map( | ||
26 | " | ||
27 | //- /lib.rs | ||
28 | mod foo; | ||
29 | |||
30 | use crate::foo::bar::Baz; | ||
31 | <|> | ||
32 | |||
33 | //- /foo/mod.rs | ||
34 | pub mod bar; | ||
35 | |||
36 | //- /foo/bar.rs | ||
37 | pub struct Baz; | ||
38 | ", | ||
39 | ); | ||
40 | let name = SmolStr::from("Baz"); | ||
41 | let resolution = &item_map.per_module[&module_id].items[&name]; | ||
42 | assert!(resolution.def_id.is_some()); | ||
43 | } | ||
44 | |||
45 | #[test] | ||
46 | fn item_map_across_crates() { | ||
47 | let (mut db, files) = MockDatabase::with_files( | ||
48 | " | ||
49 | //- /main.rs | ||
50 | use test_crate::Baz; | ||
51 | |||
52 | //- /lib.rs | ||
53 | pub struct Baz; | ||
54 | ", | ||
55 | ); | ||
56 | let main_id = files.file_id("/main.rs"); | ||
57 | let lib_id = files.file_id("/lib.rs"); | ||
58 | |||
59 | let mut crate_graph = CrateGraph::default(); | ||
60 | let main_crate = crate_graph.add_crate_root(main_id); | ||
61 | let lib_crate = crate_graph.add_crate_root(lib_id); | ||
62 | crate_graph.add_dep(main_crate, "test_crate".into(), lib_crate); | ||
63 | |||
64 | db.set_crate_graph(crate_graph); | ||
65 | |||
66 | let source_root = db.file_source_root(main_id); | ||
67 | let module = hir::source_binder::module_from_file_id(&db, main_id) | ||
68 | .unwrap() | ||
69 | .unwrap(); | ||
70 | let module_id = module.module_id; | ||
71 | let item_map = db.item_map(source_root).unwrap(); | ||
72 | |||
73 | let name = SmolStr::from("Baz"); | ||
74 | let resolution = &item_map.per_module[&module_id].items[&name]; | ||
75 | assert!(resolution.def_id.is_some()); | ||
76 | } | ||
77 | |||
78 | #[test] | ||
79 | fn typing_inside_a_function_should_not_invalidate_item_map() { | ||
80 | let (mut db, pos) = MockDatabase::with_position( | ||
81 | " | ||
82 | //- /lib.rs | ||
83 | mod foo;<|> | ||
84 | |||
85 | use crate::foo::bar::Baz; | ||
86 | |||
87 | fn foo() -> i32 { | ||
88 | 1 + 1 | ||
89 | } | ||
90 | //- /foo/mod.rs | ||
91 | pub mod bar; | ||
92 | |||
93 | //- /foo/bar.rs | ||
94 | pub struct Baz; | ||
95 | ", | ||
96 | ); | ||
97 | let source_root = db.file_source_root(pos.file_id); | ||
98 | { | ||
99 | let events = db.log_executed(|| { | ||
100 | db.item_map(source_root).unwrap(); | ||
101 | }); | ||
102 | assert!(format!("{:?}", events).contains("item_map")) | ||
103 | } | ||
104 | |||
105 | let new_text = " | ||
106 | mod foo; | ||
107 | |||
108 | use crate::foo::bar::Baz; | ||
109 | |||
110 | fn foo() -> i32 { 92 } | ||
111 | " | ||
112 | .to_string(); | ||
113 | |||
114 | db.query_mut(ra_db::FileTextQuery) | ||
115 | .set(pos.file_id, Arc::new(new_text)); | ||
116 | |||
117 | { | ||
118 | let events = db.log_executed(|| { | ||
119 | db.item_map(source_root).unwrap(); | ||
120 | }); | ||
121 | assert!( | ||
122 | !format!("{:?}", events).contains("_item_map"), | ||
123 | "{:#?}", | ||
124 | events | ||
125 | ) | ||
126 | } | ||
127 | } | ||
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs index e4d721601..37c4f9e4f 100644 --- a/crates/ra_hir/src/query_definitions.rs +++ b/crates/ra_hir/src/query_definitions.rs | |||
@@ -36,7 +36,7 @@ pub(super) fn fn_scopes(db: &impl HirDatabase, fn_id: FnId) -> Arc<FnScopes> { | |||
36 | } | 36 | } |
37 | 37 | ||
38 | pub(super) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<SourceFileItems> { | 38 | pub(super) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<SourceFileItems> { |
39 | let mut res = SourceFileItems::default(); | 39 | let mut res = SourceFileItems::new(file_id); |
40 | let source_file = db.source_file(file_id); | 40 | let source_file = db.source_file(file_id); |
41 | res.alloc(source_file.syntax().owned()); | 41 | res.alloc(source_file.syntax().owned()); |
42 | let source_file = source_file.borrowed(); | 42 | let source_file = source_file.borrowed(); |
@@ -141,13 +141,8 @@ pub(super) fn item_map( | |||
141 | Ok((id, items)) | 141 | Ok((id, items)) |
142 | }) | 142 | }) |
143 | .collect::<Cancelable<FxHashMap<_, _>>>()?; | 143 | .collect::<Cancelable<FxHashMap<_, _>>>()?; |
144 | let resolver = Resolver { | 144 | |
145 | db: db, | 145 | let resolver = Resolver::new(db, &input, source_root, module_tree); |
146 | input: &input, | ||
147 | source_root, | ||
148 | module_tree, | ||
149 | result: ItemMap::default(), | ||
150 | }; | ||
151 | let res = resolver.resolve()?; | 146 | let res = resolver.resolve()?; |
152 | let elapsed = start.elapsed(); | 147 | let elapsed = start.elapsed(); |
153 | log::info!("item_map: {:?}", elapsed); | 148 | log::info!("item_map: {:?}", elapsed); |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 479155805..0c16ccc24 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -75,7 +75,7 @@ pub fn function_from_source( | |||
75 | ) -> Cancelable<Option<Function>> { | 75 | ) -> Cancelable<Option<Function>> { |
76 | let module = ctry!(module_from_child_node(db, file_id, fn_def.syntax())?); | 76 | let module = ctry!(module_from_child_node(db, file_id, fn_def.syntax())?); |
77 | let file_items = db.file_items(file_id); | 77 | let file_items = db.file_items(file_id); |
78 | let item_id = file_items.id_of(fn_def.syntax()); | 78 | let item_id = file_items.id_of(file_id, fn_def.syntax()); |
79 | let source_item_id = SourceItemId { file_id, item_id }; | 79 | let source_item_id = SourceItemId { file_id, item_id }; |
80 | let def_loc = DefLoc { | 80 | let def_loc = DefLoc { |
81 | kind: DefKind::Function, | 81 | kind: DefKind::Function, |
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index 79d86f9b2..5ee218b6b 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml | |||
@@ -6,6 +6,7 @@ authors = ["Aleksey Kladov <[email protected]>"] | |||
6 | 6 | ||
7 | [dependencies] | 7 | [dependencies] |
8 | rayon = "1.0.2" | 8 | rayon = "1.0.2" |
9 | threadpool = "1.7.1" | ||
9 | relative-path = "0.4.0" | 10 | relative-path = "0.4.0" |
10 | failure = "0.1.2" | 11 | failure = "0.1.2" |
11 | failure_derive = "0.1.2" | 12 | failure_derive = "0.1.2" |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 0e1878906..41f70f263 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -9,7 +9,8 @@ use gen_lsp_server::{ | |||
9 | }; | 9 | }; |
10 | use languageserver_types::NumberOrString; | 10 | use languageserver_types::NumberOrString; |
11 | use ra_analysis::{Canceled, FileId, LibraryData}; | 11 | use ra_analysis::{Canceled, FileId, LibraryData}; |
12 | use rayon::{self, ThreadPool}; | 12 | use rayon; |
13 | use threadpool::ThreadPool; | ||
13 | use rustc_hash::FxHashSet; | 14 | use rustc_hash::FxHashSet; |
14 | use serde::{de::DeserializeOwned, Serialize}; | 15 | use serde::{de::DeserializeOwned, Serialize}; |
15 | use failure::{format_err, bail}; | 16 | use failure::{format_err, bail}; |
@@ -54,11 +55,7 @@ pub fn main_loop( | |||
54 | msg_receiver: &Receiver<RawMessage>, | 55 | msg_receiver: &Receiver<RawMessage>, |
55 | msg_sender: &Sender<RawMessage>, | 56 | msg_sender: &Sender<RawMessage>, |
56 | ) -> Result<()> { | 57 | ) -> Result<()> { |
57 | let pool = rayon::ThreadPoolBuilder::new() | 58 | let pool = ThreadPool::new(8); |
58 | .num_threads(4) | ||
59 | .panic_handler(|_| log::error!("thread panicked :(")) | ||
60 | .build() | ||
61 | .unwrap(); | ||
62 | let (task_sender, task_receiver) = unbounded::<Task>(); | 59 | let (task_sender, task_receiver) = unbounded::<Task>(); |
63 | let (fs_worker, fs_watcher) = vfs::roots_loader(); | 60 | let (fs_worker, fs_watcher) = vfs::roots_loader(); |
64 | let (ws_worker, ws_watcher) = workspace_loader(); | 61 | let (ws_worker, ws_watcher) = workspace_loader(); |
@@ -155,7 +152,7 @@ fn main_loop_inner( | |||
155 | } else { | 152 | } else { |
156 | let (files, resolver) = state.events_to_files(events); | 153 | let (files, resolver) = state.events_to_files(events); |
157 | let sender = libdata_sender.clone(); | 154 | let sender = libdata_sender.clone(); |
158 | pool.spawn(move || { | 155 | pool.execute(move || { |
159 | let start = ::std::time::Instant::now(); | 156 | let start = ::std::time::Instant::now(); |
160 | log::info!("indexing {} ... ", root.display()); | 157 | log::info!("indexing {} ... ", root.display()); |
161 | let data = LibraryData::prepare(files, resolver); | 158 | let data = LibraryData::prepare(files, resolver); |
@@ -321,7 +318,14 @@ fn on_notification( | |||
321 | panic!("string id's not supported: {:?}", id); | 318 | panic!("string id's not supported: {:?}", id); |
322 | } | 319 | } |
323 | }; | 320 | }; |
324 | pending_requests.remove(&id); | 321 | if pending_requests.remove(&id) { |
322 | let response = RawResponse::err( | ||
323 | id, | ||
324 | ErrorCode::RequestCancelled as i32, | ||
325 | "canceled by client".to_string(), | ||
326 | ); | ||
327 | msg_sender.send(RawMessage::Response(response)) | ||
328 | } | ||
325 | return Ok(()); | 329 | return Ok(()); |
326 | } | 330 | } |
327 | Err(not) => not, | 331 | Err(not) => not, |
@@ -402,7 +406,7 @@ impl<'a> PoolDispatcher<'a> { | |||
402 | Ok((id, params)) => { | 406 | Ok((id, params)) => { |
403 | let world = self.world.snapshot(); | 407 | let world = self.world.snapshot(); |
404 | let sender = self.sender.clone(); | 408 | let sender = self.sender.clone(); |
405 | self.pool.spawn(move || { | 409 | self.pool.execute(move || { |
406 | let resp = match f(world, params) { | 410 | let resp = match f(world, params) { |
407 | Ok(resp) => RawResponse::ok::<R>(id, &resp), | 411 | Ok(resp) => RawResponse::ok::<R>(id, &resp), |
408 | Err(e) => match e.downcast::<LspError>() { | 412 | Err(e) => match e.downcast::<LspError>() { |
@@ -452,7 +456,7 @@ fn update_file_notifications_on_threadpool( | |||
452 | sender: Sender<Task>, | 456 | sender: Sender<Task>, |
453 | subscriptions: Vec<FileId>, | 457 | subscriptions: Vec<FileId>, |
454 | ) { | 458 | ) { |
455 | pool.spawn(move || { | 459 | pool.execute(move || { |
456 | for file_id in subscriptions { | 460 | for file_id in subscriptions { |
457 | match handlers::publish_diagnostics(&world, file_id) { | 461 | match handlers::publish_diagnostics(&world, file_id) { |
458 | Err(e) => { | 462 | Err(e) => { |
diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs index 3305d468a..cb91ada90 100644 --- a/crates/ra_lsp_server/src/project_model.rs +++ b/crates/ra_lsp_server/src/project_model.rs | |||
@@ -1,6 +1,5 @@ | |||
1 | use std::path::{Path, PathBuf}; | 1 | use std::path::{Path, PathBuf}; |
2 | 2 | ||
3 | use serde_derive::Serialize; | ||
4 | use cargo_metadata::{metadata_run, CargoOpt}; | 3 | use cargo_metadata::{metadata_run, CargoOpt}; |
5 | use ra_syntax::SmolStr; | 4 | use ra_syntax::SmolStr; |
6 | use rustc_hash::{FxHashMap, FxHashSet}; | 5 | use rustc_hash::{FxHashMap, FxHashSet}; |
@@ -11,15 +10,22 @@ use crate::{ | |||
11 | thread_watcher::{ThreadWatcher, Worker}, | 10 | thread_watcher::{ThreadWatcher, Worker}, |
12 | }; | 11 | }; |
13 | 12 | ||
13 | /// `CargoWorksapce` represents the logical structure of, well, a Cargo | ||
14 | /// workspace. It pretty closely mirrors `cargo metadata` output. | ||
15 | /// | ||
16 | /// Note that internally, rust analyzer uses a differnet structure: | ||
17 | /// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates, | ||
18 | /// while this knows about `Pacakges` & `Targets`: purely cargo-related | ||
19 | /// concepts. | ||
14 | #[derive(Debug, Clone)] | 20 | #[derive(Debug, Clone)] |
15 | pub struct CargoWorkspace { | 21 | pub struct CargoWorkspace { |
16 | packages: Vec<PackageData>, | 22 | packages: Vec<PackageData>, |
17 | targets: Vec<TargetData>, | 23 | targets: Vec<TargetData>, |
18 | } | 24 | } |
19 | 25 | ||
20 | #[derive(Clone, Copy, Debug, Serialize)] | 26 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
21 | pub struct Package(usize); | 27 | pub struct Package(usize); |
22 | #[derive(Clone, Copy, Debug, Serialize)] | 28 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
23 | pub struct Target(usize); | 29 | pub struct Target(usize); |
24 | 30 | ||
25 | #[derive(Debug, Clone)] | 31 | #[derive(Debug, Clone)] |
@@ -28,6 +34,13 @@ struct PackageData { | |||
28 | manifest: PathBuf, | 34 | manifest: PathBuf, |
29 | targets: Vec<Target>, | 35 | targets: Vec<Target>, |
30 | is_member: bool, | 36 | is_member: bool, |
37 | dependencies: Vec<PackageDependency>, | ||
38 | } | ||
39 | |||
40 | #[derive(Debug, Clone)] | ||
41 | pub struct PackageDependency { | ||
42 | pub pkg: Package, | ||
43 | pub name: SmolStr, | ||
31 | } | 44 | } |
32 | 45 | ||
33 | #[derive(Debug, Clone)] | 46 | #[derive(Debug, Clone)] |
@@ -61,6 +74,12 @@ impl Package { | |||
61 | pub fn is_member(self, ws: &CargoWorkspace) -> bool { | 74 | pub fn is_member(self, ws: &CargoWorkspace) -> bool { |
62 | ws.pkg(self).is_member | 75 | ws.pkg(self).is_member |
63 | } | 76 | } |
77 | pub fn dependencies<'a>( | ||
78 | self, | ||
79 | ws: &'a CargoWorkspace, | ||
80 | ) -> impl Iterator<Item = &'a PackageDependency> + 'a { | ||
81 | ws.pkg(self).dependencies.iter() | ||
82 | } | ||
64 | } | 83 | } |
65 | 84 | ||
66 | impl Target { | 85 | impl Target { |
@@ -106,6 +125,7 @@ impl CargoWorkspace { | |||
106 | manifest: PathBuf::from(meta_pkg.manifest_path), | 125 | manifest: PathBuf::from(meta_pkg.manifest_path), |
107 | targets: Vec::new(), | 126 | targets: Vec::new(), |
108 | is_member, | 127 | is_member, |
128 | dependencies: Vec::new(), | ||
109 | }; | 129 | }; |
110 | for meta_tgt in meta_pkg.targets { | 130 | for meta_tgt in meta_pkg.targets { |
111 | let tgt = Target(targets.len()); | 131 | let tgt = Target(targets.len()); |
@@ -119,6 +139,16 @@ impl CargoWorkspace { | |||
119 | } | 139 | } |
120 | packages.push(pkg_data) | 140 | packages.push(pkg_data) |
121 | } | 141 | } |
142 | let resolve = meta.resolve.expect("metadata executed with deps"); | ||
143 | for node in resolve.nodes { | ||
144 | let source = pkg_by_id[&node.id]; | ||
145 | for id in node.dependencies { | ||
146 | let target = pkg_by_id[&id]; | ||
147 | let name: SmolStr = packages[target.0].name.replace('-', "_").into(); | ||
148 | let dep = PackageDependency { name, pkg: target }; | ||
149 | packages[source.0].dependencies.push(dep); | ||
150 | } | ||
151 | } | ||
122 | 152 | ||
123 | Ok(CargoWorkspace { packages, targets }) | 153 | Ok(CargoWorkspace { packages, targets }) |
124 | } | 154 | } |
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index c3f89ad5f..ab4c2c8aa 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs | |||
@@ -13,7 +13,7 @@ use failure::{bail, format_err}; | |||
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | path_map::{PathMap, Root}, | 15 | path_map::{PathMap, Root}, |
16 | project_model::CargoWorkspace, | 16 | project_model::{CargoWorkspace, TargetKind}, |
17 | vfs::{FileEvent, FileEventKind}, | 17 | vfs::{FileEvent, FileEventKind}, |
18 | Result, | 18 | Result, |
19 | }; | 19 | }; |
@@ -142,17 +142,34 @@ impl ServerWorldState { | |||
142 | } | 142 | } |
143 | pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) { | 143 | pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) { |
144 | let mut crate_graph = CrateGraph::default(); | 144 | let mut crate_graph = CrateGraph::default(); |
145 | ws.iter() | 145 | let mut pkg_to_lib_crate = FxHashMap::default(); |
146 | .flat_map(|ws| { | 146 | let mut pkg_crates = FxHashMap::default(); |
147 | ws.packages() | 147 | for ws in ws.iter() { |
148 | .flat_map(move |pkg| pkg.targets(ws)) | 148 | for pkg in ws.packages() { |
149 | .map(move |tgt| tgt.root(ws)) | 149 | for tgt in pkg.targets(ws) { |
150 | }) | 150 | let root = tgt.root(ws); |
151 | .for_each(|root| { | 151 | if let Some(file_id) = self.path_map.get_id(root) { |
152 | if let Some(file_id) = self.path_map.get_id(root) { | 152 | let crate_id = crate_graph.add_crate_root(file_id); |
153 | crate_graph.add_crate_root(file_id); | 153 | if tgt.kind(ws) == TargetKind::Lib { |
154 | pkg_to_lib_crate.insert(pkg, crate_id); | ||
155 | } | ||
156 | pkg_crates | ||
157 | .entry(pkg) | ||
158 | .or_insert_with(Vec::new) | ||
159 | .push(crate_id); | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | for pkg in ws.packages() { | ||
164 | for dep in pkg.dependencies(ws) { | ||
165 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { | ||
166 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | ||
167 | crate_graph.add_dep(from, dep.name.clone(), to); | ||
168 | } | ||
169 | } | ||
154 | } | 170 | } |
155 | }); | 171 | } |
172 | } | ||
156 | self.workspaces = Arc::new(ws); | 173 | self.workspaces = Arc::new(ws); |
157 | let mut change = AnalysisChange::new(); | 174 | let mut change = AnalysisChange::new(); |
158 | change.set_crate_graph(crate_graph); | 175 | change.set_crate_graph(crate_graph); |
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json index e74fd2a63..0b6d72917 100644 --- a/editors/code/package-lock.json +++ b/editors/code/package-lock.json | |||
@@ -437,7 +437,7 @@ | |||
437 | }, | 437 | }, |
438 | "css-select": { | 438 | "css-select": { |
439 | "version": "1.2.0", | 439 | "version": "1.2.0", |
440 | "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", | 440 | "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", |
441 | "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", | 441 | "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", |
442 | "dev": true, | 442 | "dev": true, |
443 | "requires": { | 443 | "requires": { |
@@ -473,7 +473,7 @@ | |||
473 | }, | 473 | }, |
474 | "deep-assign": { | 474 | "deep-assign": { |
475 | "version": "1.0.0", | 475 | "version": "1.0.0", |
476 | "resolved": "http://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", | 476 | "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", |
477 | "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", | 477 | "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", |
478 | "dev": true, | 478 | "dev": true, |
479 | "requires": { | 479 | "requires": { |
@@ -519,7 +519,7 @@ | |||
519 | "dependencies": { | 519 | "dependencies": { |
520 | "domelementtype": { | 520 | "domelementtype": { |
521 | "version": "1.1.3", | 521 | "version": "1.1.3", |
522 | "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", | 522 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", |
523 | "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", | 523 | "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", |
524 | "dev": true | 524 | "dev": true |
525 | } | 525 | } |
@@ -553,7 +553,8 @@ | |||
553 | "duplexer": { | 553 | "duplexer": { |
554 | "version": "0.1.1", | 554 | "version": "0.1.1", |
555 | "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", | 555 | "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", |
556 | "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" | 556 | "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", |
557 | "dev": true | ||
557 | }, | 558 | }, |
558 | "duplexify": { | 559 | "duplexify": { |
559 | "version": "3.6.1", | 560 | "version": "3.6.1", |
@@ -637,16 +638,17 @@ | |||
637 | "dev": true | 638 | "dev": true |
638 | }, | 639 | }, |
639 | "event-stream": { | 640 | "event-stream": { |
640 | "version": "4.0.1", | 641 | "version": "3.3.4", |
641 | "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz", | 642 | "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", |
642 | "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==", | 643 | "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", |
644 | "dev": true, | ||
643 | "requires": { | 645 | "requires": { |
644 | "duplexer": "0.1.1", | 646 | "duplexer": "0.1.1", |
645 | "from": "0.1.7", | 647 | "from": "0.1.7", |
646 | "map-stream": "0.0.7", | 648 | "map-stream": "0.1.0", |
647 | "pause-stream": "0.0.11", | 649 | "pause-stream": "0.0.11", |
648 | "split": "1.0.1", | 650 | "split": "0.3.3", |
649 | "stream-combiner": "0.2.2", | 651 | "stream-combiner": "0.0.4", |
650 | "through": "2.3.8" | 652 | "through": "2.3.8" |
651 | } | 653 | } |
652 | }, | 654 | }, |
@@ -748,7 +750,8 @@ | |||
748 | "from": { | 750 | "from": { |
749 | "version": "0.1.7", | 751 | "version": "0.1.7", |
750 | "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", | 752 | "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", |
751 | "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" | 753 | "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", |
754 | "dev": true | ||
752 | }, | 755 | }, |
753 | "fs-mkdirp-stream": { | 756 | "fs-mkdirp-stream": { |
754 | "version": "1.0.0", | 757 | "version": "1.0.0", |
@@ -925,13 +928,13 @@ | |||
925 | }, | 928 | }, |
926 | "string_decoder": { | 929 | "string_decoder": { |
927 | "version": "0.10.31", | 930 | "version": "0.10.31", |
928 | "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", | 931 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", |
929 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", | 932 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", |
930 | "dev": true | 933 | "dev": true |
931 | }, | 934 | }, |
932 | "through2": { | 935 | "through2": { |
933 | "version": "0.6.5", | 936 | "version": "0.6.5", |
934 | "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", | 937 | "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", |
935 | "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", | 938 | "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", |
936 | "dev": true, | 939 | "dev": true, |
937 | "requires": { | 940 | "requires": { |
@@ -966,45 +969,6 @@ | |||
966 | "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", | 969 | "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", |
967 | "dev": true | 970 | "dev": true |
968 | }, | 971 | }, |
969 | "event-stream": { | ||
970 | "version": "3.3.4", | ||
971 | "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", | ||
972 | "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", | ||
973 | "dev": true, | ||
974 | "requires": { | ||
975 | "duplexer": "0.1.1", | ||
976 | "from": "0.1.7", | ||
977 | "map-stream": "0.1.0", | ||
978 | "pause-stream": "0.0.11", | ||
979 | "split": "0.3.3", | ||
980 | "stream-combiner": "0.0.4", | ||
981 | "through": "2.3.8" | ||
982 | } | ||
983 | }, | ||
984 | "map-stream": { | ||
985 | "version": "0.1.0", | ||
986 | "resolved": "http://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", | ||
987 | "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", | ||
988 | "dev": true | ||
989 | }, | ||
990 | "split": { | ||
991 | "version": "0.3.3", | ||
992 | "resolved": "http://registry.npmjs.org/split/-/split-0.3.3.tgz", | ||
993 | "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", | ||
994 | "dev": true, | ||
995 | "requires": { | ||
996 | "through": "2.3.8" | ||
997 | } | ||
998 | }, | ||
999 | "stream-combiner": { | ||
1000 | "version": "0.0.4", | ||
1001 | "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", | ||
1002 | "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", | ||
1003 | "dev": true, | ||
1004 | "requires": { | ||
1005 | "duplexer": "0.1.1" | ||
1006 | } | ||
1007 | }, | ||
1008 | "vinyl": { | 972 | "vinyl": { |
1009 | "version": "2.2.0", | 973 | "version": "2.2.0", |
1010 | "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", | 974 | "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", |
@@ -1027,7 +991,7 @@ | |||
1027 | "integrity": "sha512-0QfbCH2a1k2qkTLWPqTX+QO4qNsHn3kC546YhAP3/n0h+nvtyGITDuDrYBMDZeW4WnFijmkOvBWa5HshTic1tw==", | 991 | "integrity": "sha512-0QfbCH2a1k2qkTLWPqTX+QO4qNsHn3kC546YhAP3/n0h+nvtyGITDuDrYBMDZeW4WnFijmkOvBWa5HshTic1tw==", |
1028 | "dev": true, | 992 | "dev": true, |
1029 | "requires": { | 993 | "requires": { |
1030 | "event-stream": "3.3.5", | 994 | "event-stream": "3.3.4", |
1031 | "streamifier": "0.1.1", | 995 | "streamifier": "0.1.1", |
1032 | "tar": "2.2.1", | 996 | "tar": "2.2.1", |
1033 | "through2": "2.0.5", | 997 | "through2": "2.0.5", |
@@ -1040,21 +1004,6 @@ | |||
1040 | "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", | 1004 | "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", |
1041 | "dev": true | 1005 | "dev": true |
1042 | }, | 1006 | }, |
1043 | "event-stream": { | ||
1044 | "version": "3.3.5", | ||
1045 | "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz", | ||
1046 | "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==", | ||
1047 | "dev": true, | ||
1048 | "requires": { | ||
1049 | "duplexer": "0.1.1", | ||
1050 | "from": "0.1.7", | ||
1051 | "map-stream": "0.0.7", | ||
1052 | "pause-stream": "0.0.11", | ||
1053 | "split": "1.0.1", | ||
1054 | "stream-combiner": "0.2.2", | ||
1055 | "through": "2.3.8" | ||
1056 | } | ||
1057 | }, | ||
1058 | "replace-ext": { | 1007 | "replace-ext": { |
1059 | "version": "0.0.1", | 1008 | "version": "0.0.1", |
1060 | "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", | 1009 | "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", |
@@ -1101,45 +1050,6 @@ | |||
1101 | "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", | 1050 | "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", |
1102 | "dev": true | 1051 | "dev": true |
1103 | }, | 1052 | }, |
1104 | "event-stream": { | ||
1105 | "version": "3.3.4", | ||
1106 | "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", | ||
1107 | "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", | ||
1108 | "dev": true, | ||
1109 | "requires": { | ||
1110 | "duplexer": "0.1.1", | ||
1111 | "from": "0.1.7", | ||
1112 | "map-stream": "0.1.0", | ||
1113 | "pause-stream": "0.0.11", | ||
1114 | "split": "0.3.3", | ||
1115 | "stream-combiner": "0.0.4", | ||
1116 | "through": "2.3.8" | ||
1117 | } | ||
1118 | }, | ||
1119 | "map-stream": { | ||
1120 | "version": "0.1.0", | ||
1121 | "resolved": "http://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", | ||
1122 | "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", | ||
1123 | "dev": true | ||
1124 | }, | ||
1125 | "split": { | ||
1126 | "version": "0.3.3", | ||
1127 | "resolved": "http://registry.npmjs.org/split/-/split-0.3.3.tgz", | ||
1128 | "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", | ||
1129 | "dev": true, | ||
1130 | "requires": { | ||
1131 | "through": "2.3.8" | ||
1132 | } | ||
1133 | }, | ||
1134 | "stream-combiner": { | ||
1135 | "version": "0.0.4", | ||
1136 | "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", | ||
1137 | "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", | ||
1138 | "dev": true, | ||
1139 | "requires": { | ||
1140 | "duplexer": "0.1.1" | ||
1141 | } | ||
1142 | }, | ||
1143 | "vinyl": { | 1053 | "vinyl": { |
1144 | "version": "2.2.0", | 1054 | "version": "2.2.0", |
1145 | "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", | 1055 | "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", |
@@ -1421,7 +1331,7 @@ | |||
1421 | }, | 1331 | }, |
1422 | "kind-of": { | 1332 | "kind-of": { |
1423 | "version": "1.1.0", | 1333 | "version": "1.1.0", |
1424 | "resolved": "http://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", | 1334 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", |
1425 | "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", | 1335 | "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", |
1426 | "dev": true | 1336 | "dev": true |
1427 | }, | 1337 | }, |
@@ -1485,9 +1395,10 @@ | |||
1485 | "dev": true | 1395 | "dev": true |
1486 | }, | 1396 | }, |
1487 | "map-stream": { | 1397 | "map-stream": { |
1488 | "version": "0.0.7", | 1398 | "version": "0.1.0", |
1489 | "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", | 1399 | "resolved": "http://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", |
1490 | "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=" | 1400 | "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", |
1401 | "dev": true | ||
1491 | }, | 1402 | }, |
1492 | "markdown-it": { | 1403 | "markdown-it": { |
1493 | "version": "8.4.2", | 1404 | "version": "8.4.2", |
@@ -1724,13 +1635,13 @@ | |||
1724 | }, | 1635 | }, |
1725 | "os-homedir": { | 1636 | "os-homedir": { |
1726 | "version": "1.0.2", | 1637 | "version": "1.0.2", |
1727 | "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", | 1638 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", |
1728 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", | 1639 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", |
1729 | "dev": true | 1640 | "dev": true |
1730 | }, | 1641 | }, |
1731 | "os-tmpdir": { | 1642 | "os-tmpdir": { |
1732 | "version": "1.0.2", | 1643 | "version": "1.0.2", |
1733 | "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", | 1644 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", |
1734 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", | 1645 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", |
1735 | "dev": true | 1646 | "dev": true |
1736 | }, | 1647 | }, |
@@ -1746,7 +1657,7 @@ | |||
1746 | }, | 1657 | }, |
1747 | "parse-semver": { | 1658 | "parse-semver": { |
1748 | "version": "1.1.1", | 1659 | "version": "1.1.1", |
1749 | "resolved": "http://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", | 1660 | "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", |
1750 | "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", | 1661 | "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", |
1751 | "dev": true, | 1662 | "dev": true, |
1752 | "requires": { | 1663 | "requires": { |
@@ -1784,6 +1695,7 @@ | |||
1784 | "version": "0.0.11", | 1695 | "version": "0.0.11", |
1785 | "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", | 1696 | "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", |
1786 | "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", | 1697 | "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", |
1698 | "dev": true, | ||
1787 | "requires": { | 1699 | "requires": { |
1788 | "through": "2.3.8" | 1700 | "through": "2.3.8" |
1789 | } | 1701 | } |
@@ -2033,9 +1945,10 @@ | |||
2033 | } | 1945 | } |
2034 | }, | 1946 | }, |
2035 | "split": { | 1947 | "split": { |
2036 | "version": "1.0.1", | 1948 | "version": "0.3.3", |
2037 | "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", | 1949 | "resolved": "http://registry.npmjs.org/split/-/split-0.3.3.tgz", |
2038 | "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", | 1950 | "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", |
1951 | "dev": true, | ||
2039 | "requires": { | 1952 | "requires": { |
2040 | "through": "2.3.8" | 1953 | "through": "2.3.8" |
2041 | } | 1954 | } |
@@ -2070,12 +1983,12 @@ | |||
2070 | "dev": true | 1983 | "dev": true |
2071 | }, | 1984 | }, |
2072 | "stream-combiner": { | 1985 | "stream-combiner": { |
2073 | "version": "0.2.2", | 1986 | "version": "0.0.4", |
2074 | "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", | 1987 | "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", |
2075 | "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", | 1988 | "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", |
1989 | "dev": true, | ||
2076 | "requires": { | 1990 | "requires": { |
2077 | "duplexer": "0.1.1", | 1991 | "duplexer": "0.1.1" |
2078 | "through": "2.3.8" | ||
2079 | } | 1992 | } |
2080 | }, | 1993 | }, |
2081 | "stream-shift": { | 1994 | "stream-shift": { |
@@ -2154,7 +2067,7 @@ | |||
2154 | }, | 2067 | }, |
2155 | "tar": { | 2068 | "tar": { |
2156 | "version": "2.2.1", | 2069 | "version": "2.2.1", |
2157 | "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", | 2070 | "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", |
2158 | "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", | 2071 | "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", |
2159 | "dev": true, | 2072 | "dev": true, |
2160 | "requires": { | 2073 | "requires": { |
@@ -2166,7 +2079,8 @@ | |||
2166 | "through": { | 2079 | "through": { |
2167 | "version": "2.3.8", | 2080 | "version": "2.3.8", |
2168 | "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", | 2081 | "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", |
2169 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" | 2082 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", |
2083 | "dev": true | ||
2170 | }, | 2084 | }, |
2171 | "through2": { | 2085 | "through2": { |
2172 | "version": "2.0.5", | 2086 | "version": "2.0.5", |
@@ -2334,7 +2248,7 @@ | |||
2334 | "dependencies": { | 2248 | "dependencies": { |
2335 | "underscore": { | 2249 | "underscore": { |
2336 | "version": "1.8.3", | 2250 | "version": "1.8.3", |
2337 | "resolved": "http://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", | 2251 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", |
2338 | "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", | 2252 | "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", |
2339 | "dev": true | 2253 | "dev": true |
2340 | } | 2254 | } |
diff --git a/editors/code/package.json b/editors/code/package.json index b212e159d..f196ecc60 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -31,7 +31,6 @@ | |||
31 | "singleQuote": true | 31 | "singleQuote": true |
32 | }, | 32 | }, |
33 | "dependencies": { | 33 | "dependencies": { |
34 | "event-stream": "^4.0.1", | ||
35 | "vscode-languageclient": "^5.1.1" | 34 | "vscode-languageclient": "^5.1.1" |
36 | }, | 35 | }, |
37 | "devDependencies": { | 36 | "devDependencies": { |