switch to internal feedback

This commit is contained in:
Aleksey Kladov 2018-09-03 23:32:42 +03:00
parent 971054e4d0
commit 952da31f44
6 changed files with 35 additions and 79 deletions

View file

@ -34,7 +34,7 @@ fn main_inner() -> Result<()> {
let root = ::std::env::current_dir()?; let root = ::std::env::current_dir()?;
run_server( run_server(
m::server_capabilities(), m::server_capabilities(),
|r, s| m::main_loop(root, r, s), |r, s| m::main_loop(false, root, r, s),
receiver, receiver,
sender, sender,
)?; )?;

View file

@ -32,6 +32,7 @@ enum Task {
} }
pub fn main_loop( pub fn main_loop(
internal_mode: bool,
root: PathBuf, root: PathBuf,
msg_receriver: &mut Receiver<RawMessage>, msg_receriver: &mut Receiver<RawMessage>,
msg_sender: &mut Sender<RawMessage>, msg_sender: &mut Sender<RawMessage>,
@ -47,6 +48,7 @@ pub fn main_loop(
let mut pending_requests = HashMap::new(); let mut pending_requests = HashMap::new();
let mut subs = Subscriptions::new(); let mut subs = Subscriptions::new();
let main_res = main_loop_inner( let main_res = main_loop_inner(
internal_mode,
root, root,
&pool, &pool,
msg_sender, msg_sender,
@ -80,6 +82,7 @@ pub fn main_loop(
} }
fn main_loop_inner( fn main_loop_inner(
internal_mode: bool,
ws_root: PathBuf, ws_root: PathBuf,
pool: &ThreadPool, pool: &ThreadPool,
msg_sender: &mut Sender<RawMessage>, msg_sender: &mut Sender<RawMessage>,
@ -145,8 +148,7 @@ fn main_loop_inner(
match ws { match ws {
Ok(ws) => { Ok(ws) => {
let workspaces = vec![ws]; let workspaces = vec![ws];
let not = RawNotification::new::<req::DidReloadWorkspace>(&workspaces); feedback(internal_mode, "workspace loaded", msg_sender);
msg_sender.send(RawMessage::Notification(not));
for ws in workspaces.iter() { for ws in workspaces.iter() {
for pkg in ws.packages().filter(|pkg| !pkg.is_member(ws)) { for pkg in ws.packages().filter(|pkg| !pkg.is_member(ws)) {
debug!("sending root, {}", pkg.root(ws).to_path_buf().display()); debug!("sending root, {}", pkg.root(ws).to_path_buf().display());
@ -404,3 +406,11 @@ fn update_file_notifications_on_threadpool(
} }
}); });
} }
fn feedback(intrnal_mode: bool, msg: &str, sender: &Sender<RawMessage>) {
if !intrnal_mode {
return;
}
let not = RawNotification::new::<req::InternalFeedback>(&msg.to_string());
sender.send(RawMessage::Notification(not));
}

View file

@ -11,7 +11,7 @@ use {
thread_watcher::ThreadWatcher, thread_watcher::ThreadWatcher,
}; };
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Clone)]
pub struct CargoWorkspace { pub struct CargoWorkspace {
packages: Vec<PackageData>, packages: Vec<PackageData>,
targets: Vec<TargetData>, targets: Vec<TargetData>,
@ -22,7 +22,7 @@ pub struct Package(usize);
#[derive(Clone, Copy, Debug, Serialize)] #[derive(Clone, Copy, Debug, Serialize)]
pub struct Target(usize); pub struct Target(usize);
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Clone)]
struct PackageData { struct PackageData {
name: SmolStr, name: SmolStr,
manifest: PathBuf, manifest: PathBuf,
@ -30,7 +30,7 @@ struct PackageData {
is_member: bool, is_member: bool,
} }
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Clone)]
struct TargetData { struct TargetData {
pkg: Package, pkg: Package,
name: SmolStr, name: SmolStr,
@ -38,7 +38,7 @@ struct TargetData {
kind: TargetKind, kind: TargetKind,
} }
#[derive(Debug, Serialize, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TargetKind { pub enum TargetKind {
Bin, Lib, Example, Test, Bench, Other, Bin, Lib, Example, Test, Bench, Other,
} }
@ -47,9 +47,6 @@ impl Package {
pub fn name(self, ws: &CargoWorkspace) -> &str { pub fn name(self, ws: &CargoWorkspace) -> &str {
ws.pkg(self).name.as_str() ws.pkg(self).name.as_str()
} }
pub fn manifest(self, ws: &CargoWorkspace) -> &Path {
ws.pkg(self).manifest.as_path()
}
pub fn root(self, ws: &CargoWorkspace) -> &Path { pub fn root(self, ws: &CargoWorkspace) -> &Path {
ws.pkg(self).manifest.parent().unwrap() ws.pkg(self).manifest.parent().unwrap()
} }

View file

@ -1,7 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location}; use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location};
use url_serde; use url_serde;
use project_model::CargoWorkspace;
pub use languageserver_types::{ pub use languageserver_types::{
request::*, notification::*, request::*, notification::*,
@ -169,9 +168,9 @@ pub enum FileSystemEdit {
} }
} }
pub enum DidReloadWorkspace {} pub enum InternalFeedback {}
impl Notification for DidReloadWorkspace { impl Notification for InternalFeedback {
const METHOD: &'static str = "m/didReloadWorkspace"; const METHOD: &'static str = "internalFeedback";
type Params = Vec<CargoWorkspace>; type Params = String;
} }

View file

@ -10,7 +10,7 @@ extern crate m;
mod support; mod support;
use m::req::{Runnables, RunnablesParams, DidReloadWorkspace}; use m::req::{Runnables, RunnablesParams};
use support::project; use support::project;
@ -59,7 +59,7 @@ pub fn foo() {}
#[test] #[test]
fn test_eggs() {} fn test_eggs() {}
"#); "#);
server.wait_for_notification::<DidReloadWorkspace>(); server.wait_for_feedback("workspace loaded");
server.request::<Runnables>( server.request::<Runnables>(
RunnablesParams { RunnablesParams {
text_document: server.doc_id("tests/spam.rs"), text_document: server.doc_id("tests/spam.rs"),
@ -79,32 +79,3 @@ fn test_eggs() {}
]"# ]"#
); );
} }
#[test]
fn test_project_model() {
let server = project(r#"
//- Cargo.toml
[package]
name = "foo"
version = "0.0.0"
//- src/lib.rs
pub fn foo() {}
"#);
server.notification::<DidReloadWorkspace>(r#"[
{
"packages": [
{
"is_member": true,
"manifest": "$PROJECT_ROOT$/Cargo.toml",
"name": "foo",
"targets": [ 0 ]
}
],
"targets": [
{ "kind": "Lib", "name": "foo", "pkg": 0, "root": "$PROJECT_ROOT$/src/lib.rs" }
]
}
]"#
);
}

View file

@ -14,7 +14,7 @@ use languageserver_types::{
Url, Url,
TextDocumentIdentifier, TextDocumentIdentifier,
request::{Request, Shutdown}, request::{Request, Shutdown},
notification::{Notification, DidOpenTextDocument}, notification::DidOpenTextDocument,
DidOpenTextDocumentParams, DidOpenTextDocumentParams,
TextDocumentItem, TextDocumentItem,
}; };
@ -22,7 +22,7 @@ use serde::Serialize;
use serde_json::{Value, from_str, to_string_pretty}; use serde_json::{Value, from_str, to_string_pretty};
use gen_lsp_server::{RawMessage, RawRequest, RawNotification}; use gen_lsp_server::{RawMessage, RawRequest, RawNotification};
use m::{Result, main_loop}; use m::{Result, main_loop, req};
pub fn project(fixture: &str) -> Server { pub fn project(fixture: &str) -> Server {
static INIT: Once = Once::new(); static INIT: Once = Once::new();
@ -72,7 +72,7 @@ impl Server {
let path = dir.path().to_path_buf(); let path = dir.path().to_path_buf();
let (client_sender, mut server_receiver) = bounded(1); let (client_sender, mut server_receiver) = bounded(1);
let (mut server_sender, client_receiver) = bounded(1); let (mut server_sender, client_receiver) = bounded(1);
let server = thread::spawn(move || main_loop(path, &mut server_receiver, &mut server_sender)); let server = thread::spawn(move || main_loop(true, path, &mut server_receiver, &mut server_sender));
let res = Server { let res = Server {
req_id: Cell::new(1), req_id: Cell::new(1),
dir, dir,
@ -125,25 +125,6 @@ impl Server {
); );
} }
pub fn notification<N>(
&self,
expected: &str,
)
where
N: Notification,
{
let expected = expected.replace("$PROJECT_ROOT$", &self.dir.path().display().to_string());
let expected: Value = from_str(&expected).unwrap();
let actual = self.wait_for_notification::<N>();
assert_eq!(
expected, actual,
"Expected:\n{}\n\
Actual:\n{}\n",
to_string_pretty(&expected).unwrap(),
to_string_pretty(&actual).unwrap(),
);
}
fn send_request<R>(&self, id: u64, params: R::Params) -> Value fn send_request<R>(&self, id: u64, params: R::Params) -> Value
where where
R: Request, R: Request,
@ -173,25 +154,23 @@ impl Server {
} }
panic!("no response"); panic!("no response");
} }
pub fn wait_for_notification<N: Notification>(&self) -> Value { pub fn wait_for_feedback(&self, feedback: &str) {
self.wait_for_notification_(N::METHOD)
}
fn wait_for_notification_(&self, method: &str) -> Value {
let f = |msg: &RawMessage| match msg { let f = |msg: &RawMessage| match msg {
RawMessage::Notification(n) if n.method == method => { RawMessage::Notification(n) if n.method == "internalFeedback" => {
Some(n.params.clone()) return n.clone().cast::<req::InternalFeedback>()
.unwrap() == feedback
} }
_ => None, _ => false,
}; };
for msg in self.messages.borrow().iter() { for msg in self.messages.borrow().iter() {
if let Some(res) = f(msg) { if f(msg) {
return res; return;
} }
} }
while let Some(msg) = self.recv() { while let Some(msg) = self.recv() {
if let Some(res) = f(&msg) { if f(&msg) {
return res; return;
} }
} }
panic!("no response") panic!("no response")