aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/server/src/main.rs2
-rw-r--r--crates/server/src/main_loop/mod.rs14
-rw-r--r--crates/server/src/project_model.rs11
-rw-r--r--crates/server/src/req.rs9
-rw-r--r--crates/server/tests/heavy_tests/main.rs33
-rw-r--r--crates/server/tests/heavy_tests/support.rs45
6 files changed, 35 insertions, 79 deletions
diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs
index 119f020d3..5c0166a61 100644
--- a/crates/server/src/main.rs
+++ b/crates/server/src/main.rs
@@ -34,7 +34,7 @@ fn main_inner() -> Result<()> {
34 let root = ::std::env::current_dir()?; 34 let root = ::std::env::current_dir()?;
35 run_server( 35 run_server(
36 m::server_capabilities(), 36 m::server_capabilities(),
37 |r, s| m::main_loop(root, r, s), 37 |r, s| m::main_loop(false, root, r, s),
38 receiver, 38 receiver,
39 sender, 39 sender,
40 )?; 40 )?;
diff --git a/crates/server/src/main_loop/mod.rs b/crates/server/src/main_loop/mod.rs
index 3d131274f..b66a24de1 100644
--- a/crates/server/src/main_loop/mod.rs
+++ b/crates/server/src/main_loop/mod.rs
@@ -32,6 +32,7 @@ enum Task {
32} 32}
33 33
34pub fn main_loop( 34pub fn main_loop(
35 internal_mode: bool,
35 root: PathBuf, 36 root: PathBuf,
36 msg_receriver: &mut Receiver<RawMessage>, 37 msg_receriver: &mut Receiver<RawMessage>,
37 msg_sender: &mut Sender<RawMessage>, 38 msg_sender: &mut Sender<RawMessage>,
@@ -47,6 +48,7 @@ pub fn main_loop(
47 let mut pending_requests = HashMap::new(); 48 let mut pending_requests = HashMap::new();
48 let mut subs = Subscriptions::new(); 49 let mut subs = Subscriptions::new();
49 let main_res = main_loop_inner( 50 let main_res = main_loop_inner(
51 internal_mode,
50 root, 52 root,
51 &pool, 53 &pool,
52 msg_sender, 54 msg_sender,
@@ -80,6 +82,7 @@ pub fn main_loop(
80} 82}
81 83
82fn main_loop_inner( 84fn main_loop_inner(
85 internal_mode: bool,
83 ws_root: PathBuf, 86 ws_root: PathBuf,
84 pool: &ThreadPool, 87 pool: &ThreadPool,
85 msg_sender: &mut Sender<RawMessage>, 88 msg_sender: &mut Sender<RawMessage>,
@@ -145,8 +148,7 @@ fn main_loop_inner(
145 match ws { 148 match ws {
146 Ok(ws) => { 149 Ok(ws) => {
147 let workspaces = vec![ws]; 150 let workspaces = vec![ws];
148 let not = RawNotification::new::<req::DidReloadWorkspace>(&workspaces); 151 feedback(internal_mode, "workspace loaded", msg_sender);
149 msg_sender.send(RawMessage::Notification(not));
150 for ws in workspaces.iter() { 152 for ws in workspaces.iter() {
151 for pkg in ws.packages().filter(|pkg| !pkg.is_member(ws)) { 153 for pkg in ws.packages().filter(|pkg| !pkg.is_member(ws)) {
152 debug!("sending root, {}", pkg.root(ws).to_path_buf().display()); 154 debug!("sending root, {}", pkg.root(ws).to_path_buf().display());
@@ -404,3 +406,11 @@ fn update_file_notifications_on_threadpool(
404 } 406 }
405 }); 407 });
406} 408}
409
410fn feedback(intrnal_mode: bool, msg: &str, sender: &Sender<RawMessage>) {
411 if !intrnal_mode {
412 return;
413 }
414 let not = RawNotification::new::<req::InternalFeedback>(&msg.to_string());
415 sender.send(RawMessage::Notification(not));
416}
diff --git a/crates/server/src/project_model.rs b/crates/server/src/project_model.rs
index 517836e62..a712106d9 100644
--- a/crates/server/src/project_model.rs
+++ b/crates/server/src/project_model.rs
@@ -11,7 +11,7 @@ use {
11 thread_watcher::ThreadWatcher, 11 thread_watcher::ThreadWatcher,
12}; 12};
13 13
14#[derive(Debug, Serialize, Clone)] 14#[derive(Debug, Clone)]
15pub struct CargoWorkspace { 15pub struct CargoWorkspace {
16 packages: Vec<PackageData>, 16 packages: Vec<PackageData>,
17 targets: Vec<TargetData>, 17 targets: Vec<TargetData>,
@@ -22,7 +22,7 @@ pub struct Package(usize);
22#[derive(Clone, Copy, Debug, Serialize)] 22#[derive(Clone, Copy, Debug, Serialize)]
23pub struct Target(usize); 23pub struct Target(usize);
24 24
25#[derive(Debug, Serialize, Clone)] 25#[derive(Debug, Clone)]
26struct PackageData { 26struct PackageData {
27 name: SmolStr, 27 name: SmolStr,
28 manifest: PathBuf, 28 manifest: PathBuf,
@@ -30,7 +30,7 @@ struct PackageData {
30 is_member: bool, 30 is_member: bool,
31} 31}
32 32
33#[derive(Debug, Serialize, Clone)] 33#[derive(Debug, Clone)]
34struct TargetData { 34struct TargetData {
35 pkg: Package, 35 pkg: Package,
36 name: SmolStr, 36 name: SmolStr,
@@ -38,7 +38,7 @@ struct TargetData {
38 kind: TargetKind, 38 kind: TargetKind,
39} 39}
40 40
41#[derive(Debug, Serialize, Clone, Copy, PartialEq, Eq)] 41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum TargetKind { 42pub enum TargetKind {
43 Bin, Lib, Example, Test, Bench, Other, 43 Bin, Lib, Example, Test, Bench, Other,
44} 44}
@@ -47,9 +47,6 @@ impl Package {
47 pub fn name(self, ws: &CargoWorkspace) -> &str { 47 pub fn name(self, ws: &CargoWorkspace) -> &str {
48 ws.pkg(self).name.as_str() 48 ws.pkg(self).name.as_str()
49 } 49 }
50 pub fn manifest(self, ws: &CargoWorkspace) -> &Path {
51 ws.pkg(self).manifest.as_path()
52 }
53 pub fn root(self, ws: &CargoWorkspace) -> &Path { 50 pub fn root(self, ws: &CargoWorkspace) -> &Path {
54 ws.pkg(self).manifest.parent().unwrap() 51 ws.pkg(self).manifest.parent().unwrap()
55 } 52 }
diff --git a/crates/server/src/req.rs b/crates/server/src/req.rs
index b9e0c3796..4af61dbbd 100644
--- a/crates/server/src/req.rs
+++ b/crates/server/src/req.rs
@@ -1,7 +1,6 @@
1use std::collections::HashMap; 1use std::collections::HashMap;
2use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location}; 2use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location};
3use url_serde; 3use url_serde;
4use project_model::CargoWorkspace;
5 4
6pub use languageserver_types::{ 5pub use languageserver_types::{
7 request::*, notification::*, 6 request::*, notification::*,
@@ -169,9 +168,9 @@ pub enum FileSystemEdit {
169 } 168 }
170} 169}
171 170
172pub enum DidReloadWorkspace {} 171pub enum InternalFeedback {}
173 172
174impl Notification for DidReloadWorkspace { 173impl Notification for InternalFeedback {
175 const METHOD: &'static str = "m/didReloadWorkspace"; 174 const METHOD: &'static str = "internalFeedback";
176 type Params = Vec<CargoWorkspace>; 175 type Params = String;
177} 176}
diff --git a/crates/server/tests/heavy_tests/main.rs b/crates/server/tests/heavy_tests/main.rs
index 78842e44f..d6e89bdf2 100644
--- a/crates/server/tests/heavy_tests/main.rs
+++ b/crates/server/tests/heavy_tests/main.rs
@@ -10,7 +10,7 @@ extern crate m;
10 10
11mod support; 11mod support;
12 12
13use m::req::{Runnables, RunnablesParams, DidReloadWorkspace}; 13use m::req::{Runnables, RunnablesParams};
14 14
15use support::project; 15use support::project;
16 16
@@ -59,7 +59,7 @@ pub fn foo() {}
59#[test] 59#[test]
60fn test_eggs() {} 60fn test_eggs() {}
61"#); 61"#);
62 server.wait_for_notification::<DidReloadWorkspace>(); 62 server.wait_for_feedback("workspace loaded");
63 server.request::<Runnables>( 63 server.request::<Runnables>(
64 RunnablesParams { 64 RunnablesParams {
65 text_document: server.doc_id("tests/spam.rs"), 65 text_document: server.doc_id("tests/spam.rs"),
@@ -79,32 +79,3 @@ fn test_eggs() {}
79 ]"# 79 ]"#
80 ); 80 );
81} 81}
82
83#[test]
84fn test_project_model() {
85 let server = project(r#"
86//- Cargo.toml
87[package]
88name = "foo"
89version = "0.0.0"
90
91//- src/lib.rs
92pub fn foo() {}
93"#);
94 server.notification::<DidReloadWorkspace>(r#"[
95 {
96 "packages": [
97 {
98 "is_member": true,
99 "manifest": "$PROJECT_ROOT$/Cargo.toml",
100 "name": "foo",
101 "targets": [ 0 ]
102 }
103 ],
104 "targets": [
105 { "kind": "Lib", "name": "foo", "pkg": 0, "root": "$PROJECT_ROOT$/src/lib.rs" }
106 ]
107 }
108]"#
109 );
110}
diff --git a/crates/server/tests/heavy_tests/support.rs b/crates/server/tests/heavy_tests/support.rs
index 38a9e6c76..99a784e8d 100644
--- a/crates/server/tests/heavy_tests/support.rs
+++ b/crates/server/tests/heavy_tests/support.rs
@@ -14,7 +14,7 @@ use languageserver_types::{
14 Url, 14 Url,
15 TextDocumentIdentifier, 15 TextDocumentIdentifier,
16 request::{Request, Shutdown}, 16 request::{Request, Shutdown},
17 notification::{Notification, DidOpenTextDocument}, 17 notification::DidOpenTextDocument,
18 DidOpenTextDocumentParams, 18 DidOpenTextDocumentParams,
19 TextDocumentItem, 19 TextDocumentItem,
20}; 20};
@@ -22,7 +22,7 @@ use serde::Serialize;
22use serde_json::{Value, from_str, to_string_pretty}; 22use serde_json::{Value, from_str, to_string_pretty};
23use gen_lsp_server::{RawMessage, RawRequest, RawNotification}; 23use gen_lsp_server::{RawMessage, RawRequest, RawNotification};
24 24
25use m::{Result, main_loop}; 25use m::{Result, main_loop, req};
26 26
27pub fn project(fixture: &str) -> Server { 27pub fn project(fixture: &str) -> Server {
28 static INIT: Once = Once::new(); 28 static INIT: Once = Once::new();
@@ -72,7 +72,7 @@ impl Server {
72 let path = dir.path().to_path_buf(); 72 let path = dir.path().to_path_buf();
73 let (client_sender, mut server_receiver) = bounded(1); 73 let (client_sender, mut server_receiver) = bounded(1);
74 let (mut server_sender, client_receiver) = bounded(1); 74 let (mut server_sender, client_receiver) = bounded(1);
75 let server = thread::spawn(move || main_loop(path, &mut server_receiver, &mut server_sender)); 75 let server = thread::spawn(move || main_loop(true, path, &mut server_receiver, &mut server_sender));
76 let res = Server { 76 let res = Server {
77 req_id: Cell::new(1), 77 req_id: Cell::new(1),
78 dir, 78 dir,
@@ -125,25 +125,6 @@ impl Server {
125 ); 125 );
126 } 126 }
127 127
128 pub fn notification<N>(
129 &self,
130 expected: &str,
131 )
132 where
133 N: Notification,
134 {
135 let expected = expected.replace("$PROJECT_ROOT$", &self.dir.path().display().to_string());
136 let expected: Value = from_str(&expected).unwrap();
137 let actual = self.wait_for_notification::<N>();
138 assert_eq!(
139 expected, actual,
140 "Expected:\n{}\n\
141 Actual:\n{}\n",
142 to_string_pretty(&expected).unwrap(),
143 to_string_pretty(&actual).unwrap(),
144 );
145 }
146
147 fn send_request<R>(&self, id: u64, params: R::Params) -> Value 128 fn send_request<R>(&self, id: u64, params: R::Params) -> Value
148 where 129 where
149 R: Request, 130 R: Request,
@@ -173,25 +154,23 @@ impl Server {
173 } 154 }
174 panic!("no response"); 155 panic!("no response");
175 } 156 }
176 pub fn wait_for_notification<N: Notification>(&self) -> Value { 157 pub fn wait_for_feedback(&self, feedback: &str) {
177 self.wait_for_notification_(N::METHOD)
178 }
179 fn wait_for_notification_(&self, method: &str) -> Value {
180 let f = |msg: &RawMessage| match msg { 158 let f = |msg: &RawMessage| match msg {
181 RawMessage::Notification(n) if n.method == method => { 159 RawMessage::Notification(n) if n.method == "internalFeedback" => {
182 Some(n.params.clone()) 160 return n.clone().cast::<req::InternalFeedback>()
161 .unwrap() == feedback
183 } 162 }
184 _ => None, 163 _ => false,
185 }; 164 };
186 165
187 for msg in self.messages.borrow().iter() { 166 for msg in self.messages.borrow().iter() {
188 if let Some(res) = f(msg) { 167 if f(msg) {
189 return res; 168 return;
190 } 169 }
191 } 170 }
192 while let Some(msg) = self.recv() { 171 while let Some(msg) = self.recv() {
193 if let Some(res) = f(&msg) { 172 if f(&msg) {
194 return res; 173 return;
195 } 174 }
196 } 175 }
197 panic!("no response") 176 panic!("no response")