Skip to content

Commit

Permalink
remove event handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mkurnikov committed Jul 5, 2020
1 parent 6c68f15 commit 2223059
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 20 deletions.
64 changes: 54 additions & 10 deletions crates/integration_tests/tests/test_lsp.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
use lsp_server::{Connection, Message, Notification, Request, RequestId, Response};
use lsp_types::request::{Initialize, Shutdown};
use lsp_types::{
ClientCapabilities, DidChangeConfigurationParams, InitializeParams, InitializedParams,
ClientCapabilities, DidChangeConfigurationParams, DidChangeWatchedFilesParams,
FileChangeType, FileEvent, InitializeParams, InitializedParams, Url,
};

use analysis::config::Config;

use dialects::DialectName;

use integration_tests::config;
use integration_tests::{config, get_script_path};

use lsp_types::notification::{DidChangeConfiguration, Initialized};
use lsp_types::notification::{DidChangeConfiguration, DidChangeWatchedFiles, Initialized};

use move_language_server::global_state::{initialize_new_global_state, GlobalState};
use move_language_server::main_loop::{main_loop, notification_new, request_new};
use move_language_server::main_loop::{
main_loop, notification_new, request_new, FileSystemEvent,
};
use move_language_server::server::run_server;

const SHUTDOWN_REQ_ID: u64 = 10;
Expand Down Expand Up @@ -58,20 +61,28 @@ fn response(req_id: usize, contents: serde_json::Value) -> Message {
trait MessageType {
fn into_request(self) -> Request;
fn into_response(self) -> Response;
fn into_notification(self) -> Notification;
}

impl MessageType for Message {
fn into_request(self) -> Request {
match self {
Message::Request(req) => req,
_ => panic!(),
_ => panic!("not a request"),
}
}

fn into_response(self) -> Response {
match self {
Message::Response(resp) => resp,
_ => panic!(),
_ => panic!("not a response"),
}
}

fn into_notification(self) -> Notification {
match self {
Message::Notification(notification) => notification,
_ => panic!("not a notification"),
}
}
}
Expand Down Expand Up @@ -115,13 +126,18 @@ fn test_server_initialization() {
assert_eq!(init_finished_resp.id, RequestId::from(1));
assert_eq!(
init_finished_resp.result.unwrap()["capabilities"]["textDocumentSync"],
1
serde_json::json!({"change": 1, "openClose": true})
);
let shutdown_req = client_conn.receiver.try_recv().unwrap();
let registration_req = client_conn.receiver.try_recv().unwrap().into_request();
assert_eq!(registration_req.method, "client/registerCapability");
assert_eq!(
shutdown_req.into_response().id,
RequestId::from(SHUTDOWN_REQ_ID)
registration_req.params["registrations"][0]["method"],
"workspace/didChangeWatchedFiles"
);

let shutdown_resp = client_conn.receiver.try_recv().unwrap().into_response();
assert_eq!(shutdown_resp.id, RequestId::from(SHUTDOWN_REQ_ID));

client_conn.receiver.try_recv().unwrap_err();
}

Expand Down Expand Up @@ -157,3 +173,31 @@ fn test_server_config_change() {
);
assert_eq!(global_state.config().dialect_name, DialectName::DFinance);
}

#[test]
fn test_removed_file_not_present_in_the_diagnostics() {
let (client_conn, server_conn) = Connection::memory();

let script_text = r"script {
use 0x0::Unknown;
fun main() {}
}";
let script_file = (get_script_path(), script_text.to_string());

let mut global_state = global_state(config!());
global_state.update_from_events(vec![FileSystemEvent::AddFile(script_file)]);

let delete_event = FileEvent::new(
Url::from_file_path(get_script_path()).unwrap(),
FileChangeType::Deleted,
);
let files_changed_notification =
notification::<DidChangeWatchedFiles>(DidChangeWatchedFilesParams {
changes: vec![delete_event],
});
send_messages(&client_conn, vec![files_changed_notification]);

main_loop(&mut global_state, &server_conn).unwrap();

assert!(global_state.analysis().db().available_files.is_empty());
}
8 changes: 4 additions & 4 deletions crates/move-language-server/src/global_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,17 @@ impl GlobalState {
}

pub fn initialize_new_global_state(config: Config) -> GlobalState {
let mut fs_events = vec![];
let mut initial_fs_events = vec![];
match &config.stdlib_folder {
Some(folder) => {
for file in io::load_move_files(vec![folder.clone()]).unwrap() {
fs_events.push(FileSystemEvent::AddFile(file));
initial_fs_events.push(FileSystemEvent::AddFile(file));
}
}
None => {}
}
for file in io::load_move_files(config.modules_folders.clone()).unwrap() {
fs_events.push(FileSystemEvent::AddFile(file));
initial_fs_events.push(FileSystemEvent::AddFile(file));
}
GlobalState::new(config, fs_events)
GlobalState::new(config, initial_fs_events)
}
21 changes: 19 additions & 2 deletions crates/move-language-server/src/main_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use anyhow::Result;
use crossbeam_channel::{unbounded, Sender};
use lsp_server::{Connection, Message, Notification, Request, RequestId, Response};
use lsp_types::notification::{
DidChangeConfiguration, DidChangeTextDocument, DidCloseTextDocument, DidOpenTextDocument,
PublishDiagnostics, ShowMessage,
DidChangeConfiguration, DidChangeTextDocument, DidChangeWatchedFiles, DidCloseTextDocument,
DidOpenTextDocument, PublishDiagnostics, ShowMessage,
};
use lsp_types::request::WorkspaceConfiguration;
use lsp_types::{
Expand Down Expand Up @@ -370,6 +370,23 @@ fn on_notification(
}
Err(not) => not,
};
let not = match notification_cast::<DidChangeWatchedFiles>(not) {
Ok(params) => {
for file_event in params.changes {
let uri = file_event.uri;
let fpath = uri
.to_file_path()
.map_err(|_| anyhow::anyhow!("invalid uri: {}", uri))?;
let fpath = leaked_fpath(fpath);
loop_state.opened_files.remove(fpath);
fs_events_sender
.send(FileSystemEvent::RemoveFile(fpath))
.unwrap();
}
return Ok(());
}
Err(not) => not,
};
if not.method.starts_with("$/") {
return Ok(());
}
Expand Down
42 changes: 38 additions & 4 deletions crates/move-language-server/src/server.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
use std::path::PathBuf;

use anyhow::Result;
use lsp_server::{Connection, ProtocolError};
use lsp_types::{ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind};
use lsp_server::{Connection, ProtocolError, RequestId};
use lsp_types::{
DidChangeWatchedFilesRegistrationOptions, FileSystemWatcher, RegistrationParams,
ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind,
TextDocumentSyncOptions, WatchKind,
};
use serde::de::DeserializeOwned;

use analysis::config::Config;

use crate::global_state::initialize_new_global_state;
use crate::main_loop;
use crate::main_loop::request_new;

fn move_language_server_capabilities() -> ServerCapabilities {
ServerCapabilities {
text_document_sync: Some(TextDocumentSyncCapability::Kind(TextDocumentSyncKind::Full)),
text_document_sync: Some(TextDocumentSyncCapability::Options(
TextDocumentSyncOptions {
open_close: Some(true),
change: Some(TextDocumentSyncKind::Full),
..TextDocumentSyncOptions::default()
},
)),
..ServerCapabilities::default()
}
}
Expand Down Expand Up @@ -45,13 +56,36 @@ pub fn parse_initialize_params(init_params: serde_json::Value) -> Result<(PathBu
Ok((root, config))
}

fn register_for_file_changes(connection: &Connection) {
let move_files_watcher = FileSystemWatcher {
glob_pattern: "**/*.move".to_string(),
kind: Some(WatchKind::Delete),
};
let registration_options = DidChangeWatchedFilesRegistrationOptions {
watchers: vec![move_files_watcher],
};
let registration = lsp_types::Registration {
id: "workspace/didChangeWatchedFiles".to_string(),
method: "workspace/didChangeWatchedFiles".to_string(),
register_options: Some(serde_json::to_value(registration_options).unwrap()),
};
let registration_req = request_new::<lsp_types::request::RegisterCapability>(
RequestId::from(1),
RegistrationParams {
registrations: vec![registration],
},
);
connection.sender.send(registration_req.into()).unwrap();
}

pub fn run_server(connection: &Connection) -> Result<()> {
let init_params = initialize_server(connection)?;
let (_, config) = parse_initialize_params(init_params)?;
log::info!("Initialization is finished");

register_for_file_changes(connection);

let mut global_state = initialize_new_global_state(config);
dbg!(&global_state.config());
main_loop::main_loop(&mut global_state, connection)
}

Expand Down

0 comments on commit 2223059

Please sign in to comment.