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()?;
run_server(
m::server_capabilities(),
|r, s| m::main_loop(root, r, s),
|r, s| m::main_loop(false, root, r, s),
receiver,
sender,
)?;

View file

@ -32,6 +32,7 @@ enum Task {
}
pub fn main_loop(
internal_mode: bool,
root: PathBuf,
msg_receriver: &mut Receiver<RawMessage>,
msg_sender: &mut Sender<RawMessage>,
@ -47,6 +48,7 @@ pub fn main_loop(
let mut pending_requests = HashMap::new();
let mut subs = Subscriptions::new();
let main_res = main_loop_inner(
internal_mode,
root,
&pool,
msg_sender,
@ -80,6 +82,7 @@ pub fn main_loop(
}
fn main_loop_inner(
internal_mode: bool,
ws_root: PathBuf,
pool: &ThreadPool,
msg_sender: &mut Sender<RawMessage>,
@ -145,8 +148,7 @@ fn main_loop_inner(
match ws {
Ok(ws) => {
let workspaces = vec![ws];
let not = RawNotification::new::<req::DidReloadWorkspace>(&workspaces);
msg_sender.send(RawMessage::Notification(not));
feedback(internal_mode, "workspace loaded", msg_sender);
for ws in workspaces.iter() {
for pkg in ws.packages().filter(|pkg| !pkg.is_member(ws)) {
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,
};
#[derive(Debug, Serialize, Clone)]
#[derive(Debug, Clone)]
pub struct CargoWorkspace {
packages: Vec<PackageData>,
targets: Vec<TargetData>,
@ -22,7 +22,7 @@ pub struct Package(usize);
#[derive(Clone, Copy, Debug, Serialize)]
pub struct Target(usize);
#[derive(Debug, Serialize, Clone)]
#[derive(Debug, Clone)]
struct PackageData {
name: SmolStr,
manifest: PathBuf,
@ -30,7 +30,7 @@ struct PackageData {
is_member: bool,
}
#[derive(Debug, Serialize, Clone)]
#[derive(Debug, Clone)]
struct TargetData {
pkg: Package,
name: SmolStr,
@ -38,7 +38,7 @@ struct TargetData {
kind: TargetKind,
}
#[derive(Debug, Serialize, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TargetKind {
Bin, Lib, Example, Test, Bench, Other,
}
@ -47,9 +47,6 @@ impl Package {
pub fn name(self, ws: &CargoWorkspace) -> &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 {
ws.pkg(self).manifest.parent().unwrap()
}

View file

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

View file

@ -10,7 +10,7 @@ extern crate m;
mod support;
use m::req::{Runnables, RunnablesParams, DidReloadWorkspace};
use m::req::{Runnables, RunnablesParams};
use support::project;
@ -59,7 +59,7 @@ pub fn foo() {}
#[test]
fn test_eggs() {}
"#);
server.wait_for_notification::<DidReloadWorkspace>();
server.wait_for_feedback("workspace loaded");
server.request::<Runnables>(
RunnablesParams {
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,
TextDocumentIdentifier,
request::{Request, Shutdown},
notification::{Notification, DidOpenTextDocument},
notification::DidOpenTextDocument,
DidOpenTextDocumentParams,
TextDocumentItem,
};
@ -22,7 +22,7 @@ use serde::Serialize;
use serde_json::{Value, from_str, to_string_pretty};
use gen_lsp_server::{RawMessage, RawRequest, RawNotification};
use m::{Result, main_loop};
use m::{Result, main_loop, req};
pub fn project(fixture: &str) -> Server {
static INIT: Once = Once::new();
@ -72,7 +72,7 @@ impl Server {
let path = dir.path().to_path_buf();
let (client_sender, mut server_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 {
req_id: Cell::new(1),
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
where
R: Request,
@ -173,25 +154,23 @@ impl Server {
}
panic!("no response");
}
pub fn wait_for_notification<N: Notification>(&self) -> Value {
self.wait_for_notification_(N::METHOD)
}
fn wait_for_notification_(&self, method: &str) -> Value {
pub fn wait_for_feedback(&self, feedback: &str) {
let f = |msg: &RawMessage| match msg {
RawMessage::Notification(n) if n.method == method => {
Some(n.params.clone())
RawMessage::Notification(n) if n.method == "internalFeedback" => {
return n.clone().cast::<req::InternalFeedback>()
.unwrap() == feedback
}
_ => None,
_ => false,
};
for msg in self.messages.borrow().iter() {
if let Some(res) = f(msg) {
return res;
if f(msg) {
return;
}
}
while let Some(msg) = self.recv() {
if let Some(res) = f(&msg) {
return res;
if f(&msg) {
return;
}
}
panic!("no response")