mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-27 04:15:08 +00:00
switch to internal feedback
This commit is contained in:
parent
971054e4d0
commit
952da31f44
6 changed files with 35 additions and 79 deletions
|
@ -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,
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]"#
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in a new issue