diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 2eb7f0da013..5c3799e95b7 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs @@ -61,6 +61,7 @@ impl HirFileId { db: &impl DefDatabase, file_id: HirFileId, ) -> Option> { + db.check_canceled(); let _p = profile("parse_or_expand_query"); match file_id.0 { HirFileIdRepr::File(file_id) => Some(db.parse(file_id).syntax().to_owned()), diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 2434f428f6b..0e64abdbd49 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs @@ -156,6 +156,10 @@ impl RootDatabase { pub(crate) fn apply_change(&mut self, change: AnalysisChange) { let _p = profile("RootDatabase::apply_change"); log::info!("apply_change {:?}", change); + { + let _p = profile("RootDatabase::apply_change/cancellation"); + self.salsa_runtime().next_revision(); + } if !change.new_roots.is_empty() { let mut local_roots = Vec::clone(&self.local_roots()); for (root_id, is_local) in change.new_roots { diff --git a/crates/ra_lsp_server/tests/heavy_tests/main.rs b/crates/ra_lsp_server/tests/heavy_tests/main.rs index 6f37a980db6..f61048aaf09 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/main.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/main.rs @@ -6,10 +6,11 @@ use std::{ }; use lsp_types::{ - CodeActionContext, DocumentFormattingParams, FormattingOptions, Position, Range, + CodeActionContext, DocumentFormattingParams, FormattingOptions, Position, Range, DidOpenTextDocumentParams, TextDocumentItem, TextDocumentPositionParams }; use ra_lsp_server::req::{ CodeActionParams, CodeActionRequest, Formatting, Runnables, RunnablesParams, CompletionParams, Completion, + DidOpenTextDocument, OnEnter, }; use serde_json::json; use tempfile::TempDir; @@ -17,6 +18,7 @@ use tempfile::TempDir; use crate::support::{project, Project}; const LOG: &'static str = ""; +const PROFILE: &'static str = "*@3>100"; #[test] fn completes_items_from_standard_library() { @@ -341,3 +343,68 @@ fn main() {{}} json!([]), ); } + +#[test] +fn diagnostics_dont_block_typing() { + let librs: String = (0..10).map(|i| format!("mod m{};", i)).collect(); + let libs: String = (0..10).map(|i| format!("//- src/m{}.rs\nfn foo() {{}}\n\n", i)).collect(); + let server = project(&format!( + r#" +//- Cargo.toml +[package] +name = "foo" +version = "0.0.0" + +//- src/lib.rs +{} + +{} + +fn main() {{}} +"#, + librs, libs + )); + server.wait_until_workspace_is_loaded(); + for i in 0..10 { + server.notification::(DidOpenTextDocumentParams { + text_document: TextDocumentItem { + uri: server.doc_id(&format!("src/m{}.rs", i)).uri, + language_id: "rust".to_string(), + version: 0, + text: "/// Docs\nfn foo() {}".to_string(), + }, + }); + } + let start = std::time::Instant::now(); + server.request::( + TextDocumentPositionParams { + text_document: server.doc_id("src/m0.rs"), + position: Position { line: 0, character: 5 }, + }, + json!({ + "cursorPosition": { + "position": { "character": 4, "line": 1 }, + "textDocument": { "uri": "file:///[..]src/m0.rs" } + }, + "label": "on enter", + "workspaceEdit": { + "documentChanges": [ + { + "edits": [ + { + "newText": "\n/// ", + "range": { + "end": { "character": 5, "line": 0 }, + "start": { "character": 5, "line": 0 } + } + } + ], + "textDocument": { "uri": "file:///[..]src/m0.rs", "version": null } + } + ] + } + }), + ); + let elapsed = start.elapsed(); + assert!(elapsed.as_millis() < 2000, "typing enter took {:?}", elapsed); +} diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index d68182174b3..729067395fc 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs @@ -52,6 +52,11 @@ impl<'a> Project<'a> { static INIT: Once = Once::new(); INIT.call_once(|| { let _ = Logger::with_env_or_str(crate::LOG).start().unwrap(); + ra_prof::set_filter(if crate::PROFILE.is_empty() { + ra_prof::Filter::disabled() + } else { + ra_prof::Filter::from_spec(&crate::PROFILE) + }); }); let mut paths = vec![]; @@ -121,6 +126,15 @@ impl Server { TextDocumentIdentifier { uri: Url::from_file_path(path).unwrap() } } + pub fn notification(&self, params: N::Params) + where + N: Notification, + N::Params: Serialize, + { + let r = RawNotification::new::(¶ms); + self.send_notification(r) + } + pub fn request(&self, params: R::Params, expected_resp: Value) where R: Request,