From 571709086ccf2c5699a1d9cee5229d066936ee5a Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sat, 12 Mar 2022 04:01:09 -0800 Subject: [PATCH 1/3] feat: update lsp_types to the latest version --- Cargo.lock | 4 +- Cargo.toml | 2 +- rls/src/actions/diagnostics.rs | 9 +- rls/src/actions/format.rs | 6 +- rls/src/actions/mod.rs | 7 +- rls/src/actions/notifications.rs | 8 +- rls/src/actions/post_build.rs | 5 +- rls/src/actions/progress.rs | 67 ++++++-- rls/src/actions/requests.rs | 46 ++++-- rls/src/cmd.rs | 126 ++++++++++----- rls/src/lsp_data.rs | 54 +++---- rls/src/server/message.rs | 6 +- rls/src/server/mod.rs | 52 +++++-- tests/client.rs | 256 ++++++++++++++++++++++--------- tests/support/harness.rs | 4 +- tests/tooltip.rs | 8 +- 16 files changed, 449 insertions(+), 211 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7171a6a0769..16d05043c85 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1193,9 +1193,9 @@ dependencies = [ [[package]] name = "lsp-types" -version = "0.60.0" +version = "0.92.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3edefcd66dde1f7f1df706f46520a3c93adc5ca4bc5747da6621195e894efd" +checksum = "e8a69d4142d51b208c9fc3cea68b1a7fcef30354e7aa6ccad07250fd8430fc76" dependencies = [ "bitflags", "serde", diff --git a/Cargo.toml b/Cargo.toml index 38deb1a2b3e..34e4a7a3cb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ env_logger = "0.9" home = "0.5.1" itertools = "0.10" jsonrpc-core = "18" -lsp-types = { version = "0.60", features = ["proposed"] } +lsp-types = { version = "0.92", features = ["proposed"] } lazy_static = "1" log = "0.4" num_cpus = "1" diff --git a/rls/src/actions/diagnostics.rs b/rls/src/actions/diagnostics.rs index 450a5bd98ad..5421dc2937d 100644 --- a/rls/src/actions/diagnostics.rs +++ b/rls/src/actions/diagnostics.rs @@ -141,6 +141,9 @@ pub fn parse_diagnostics( source: Some(source.to_owned()), message: diagnostic_message, related_information, + code_description: None, + tags: None, + data: None, }; (file_path, (diagnostic, suggestions)) @@ -193,9 +196,9 @@ fn format_notes(children: &[AssociatedMessage], primary: &DiagnosticSpan) -> Opt fn severity(level: &str, is_primary_span: bool) -> DiagnosticSeverity { match (level, is_primary_span) { - (_, false) => DiagnosticSeverity::Information, - ("error", _) => DiagnosticSeverity::Error, - (..) => DiagnosticSeverity::Warning, + (_, false) => DiagnosticSeverity::INFORMATION, + ("error", _) => DiagnosticSeverity::ERROR, + (..) => DiagnosticSeverity::WARNING, } } diff --git a/rls/src/actions/format.rs b/rls/src/actions/format.rs index b7781993a3d..b76a49c9c4e 100644 --- a/rls/src/actions/format.rs +++ b/rls/src/actions/format.rs @@ -98,8 +98,8 @@ impl Rustfmt { .into_iter() .map(|item| { // Rustfmt's line indices are 1-based - let start_line = u64::from(item.line_number_orig) - 1; - let end_line = start_line + u64::from(item.lines_removed); + let start_line = item.line_number_orig - 1; + let end_line = start_line + item.lines_removed; let mut new_text = item.lines.join(newline); @@ -242,7 +242,7 @@ mod tests { Rustfmt::Internal.calc_text_edits(input.to_string(), config()).unwrap() } - fn test_case(input: &str, output: Vec<(u64, u64, u64, u64, &str)>) { + fn test_case(input: &str, output: Vec<(u32, u32, u32, u32, &str)>) { assert_eq!( format(input), output diff --git a/rls/src/actions/mod.rs b/rls/src/actions/mod.rs index 5bc8518df1e..bb51b549be8 100644 --- a/rls/src/actions/mod.rs +++ b/rls/src/actions/mod.rs @@ -579,7 +579,7 @@ impl FileWatch { } let local = &path[self.project_uri.len()..]; - local == "/Cargo.lock" || (local == "/target" && kind == FileChangeType::Deleted) + local == "/Cargo.lock" || (local == "/target" && kind == FileChangeType::DELETED) } #[inline] @@ -589,7 +589,7 @@ impl FileWatch { #[inline] pub fn is_relevant_save_doc(&self, did_save: &DidSaveTextDocumentParams) -> bool { - self.relevant_change_kind(&did_save.text_document.uri, FileChangeType::Changed) + self.relevant_change_kind(&did_save.text_document.uri, FileChangeType::CHANGED) } } @@ -629,12 +629,13 @@ mod test { } fn change(url: &str) -> FileEvent { - FileEvent::new(Url::parse(url).unwrap(), FileChangeType::Changed) + FileEvent::new(Url::parse(url).unwrap(), FileChangeType::CHANGED) } fn did_save(url: &str) -> DidSaveTextDocumentParams { DidSaveTextDocumentParams { text_document: TextDocumentIdentifier::new(Url::parse(url).unwrap()), + text: None, } } diff --git a/rls/src/actions/notifications.rs b/rls/src/actions/notifications.rs index 4c2976bbf04..30d4ae186b3 100644 --- a/rls/src/actions/notifications.rs +++ b/rls/src/actions/notifications.rs @@ -75,14 +75,14 @@ impl BlockingNotificationAction for DidChangeTextDocument { ctx.quiescent.store(false, Ordering::SeqCst); let file_path = parse_file_path!(¶ms.text_document.uri, "on_change")?; - let version_num = params.text_document.version.unwrap(); + let version_num = params.text_document.version as u64; match ctx.check_change_version(&file_path, version_num) { VersionOrdering::Ok => {} VersionOrdering::Duplicate => return Ok(()), VersionOrdering::OutOfOrder => { out.notify(Notification::::new(ShowMessageParams { - typ: MessageType::Warning, + typ: MessageType::WARNING, message: format!("Out of order change in {:?}", file_path), })); return Ok(()); @@ -99,7 +99,7 @@ impl BlockingNotificationAction for DidChangeTextDocument { // LSP sends UTF-16 code units based offsets and length span: VfsSpan::from_utf16( Span::from_range(range, file_path.clone()), - i.range_length, + i.range_length.map(|l| l as u64), ), text: i.text.clone(), } @@ -311,7 +311,7 @@ mod test { let manifest_change = Url::parse(lsp_project_manifest).unwrap(); DidChangeWatchedFiles::handle( DidChangeWatchedFilesParams { - changes: vec![FileEvent::new(manifest_change, FileChangeType::Changed)], + changes: vec![FileEvent::new(manifest_change, FileChangeType::CHANGED)], }, &mut ctx, NoOutput, diff --git a/rls/src/actions/post_build.rs b/rls/src/actions/post_build.rs index 660f42dacfb..3f0c6fe3007 100644 --- a/rls/src/actions/post_build.rs +++ b/rls/src/actions/post_build.rs @@ -137,7 +137,7 @@ impl PostBuildHandler { Diagnostic { range, message, - severity: Some(DiagnosticSeverity::Error), + severity: Some(DiagnosticSeverity::ERROR), ..Diagnostic::default() }, vec![], @@ -206,10 +206,11 @@ impl PostBuildHandler { .iter() .map(|(diag, _)| diag) .filter(|diag| { - self.show_warnings || diag.severity != Some(DiagnosticSeverity::Warning) + self.show_warnings || diag.severity != Some(DiagnosticSeverity::WARNING) }) .cloned() .collect(), + version: None, }; self.notifier.notify_publish_diagnostics(params); diff --git a/rls/src/actions/progress.rs b/rls/src/actions/progress.rs index d7a29a82f41..6b9cb7324b8 100644 --- a/rls/src/actions/progress.rs +++ b/rls/src/actions/progress.rs @@ -3,7 +3,11 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use crate::server::{Notification, Output}; use lazy_static::lazy_static; use lsp_types::notification::{Progress, PublishDiagnostics, ShowMessage}; -use lsp_types::{MessageType, ProgressParams, PublishDiagnosticsParams, ShowMessageParams}; +use lsp_types::{ + MessageType, NumberOrString, ProgressParams, ProgressParamsValue, PublishDiagnosticsParams, + ShowMessageParams, WorkDoneProgress, WorkDoneProgressBegin, WorkDoneProgressEnd, + WorkDoneProgressReport, +}; /// Communication of build progress back to the client. pub trait ProgressNotifier: Send { @@ -37,11 +41,16 @@ fn new_progress_params(title: String) -> ProgressParams { } ProgressParams { - id: format!("progress_{}", PROGRESS_ID_COUNTER.fetch_add(1, Ordering::SeqCst)), - title, - message: None, - percentage: None, - done: None, + token: NumberOrString::String(format!( + "progress_{}", + PROGRESS_ID_COUNTER.fetch_add(1, Ordering::SeqCst) + )), + value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin(WorkDoneProgressBegin { + title, + cancellable: None, + message: None, + percentage: None, + })), } } @@ -67,15 +76,45 @@ impl ProgressNotifier for BuildProgressNotifier { } fn notify_progress(&self, update: ProgressUpdate) { let mut params = self.progress_params.clone(); - match update { - ProgressUpdate::Message(s) => params.message = Some(s), - ProgressUpdate::Percentage(p) => params.percentage = Some(p), - } + + // set the value to WorkDoneProgress::Report if it is not + match &mut params.value { + ProgressParamsValue::WorkDone(work) => match work { + WorkDoneProgress::Report(_) => {} + _ => { + params.value = ProgressParamsValue::WorkDone(WorkDoneProgress::Report( + WorkDoneProgressReport { + cancellable: None, + message: None, + percentage: None, + }, + )) + } + }, + }; + + match &mut params.value { + ProgressParamsValue::WorkDone(work) => match work { + WorkDoneProgress::Report(value) => match update { + ProgressUpdate::Message(m) => { + value.message = Some(m); + } + ProgressUpdate::Percentage(p) => { + value.percentage = Some(p as u32); + } + }, + _ => { + unreachable!("params.value is set to WorkDoneProgress::Report"); + } + }, + }; self.out.notify(Notification::::new(params)); } fn notify_end_progress(&self) { let mut params = self.progress_params.clone(); - params.done = Some(true); + params.value = ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd { + message: None, + })); self.out.notify(Notification::::new(params)); } } @@ -110,13 +149,15 @@ impl DiagnosticsNotifier for BuildDiagnosticsNotifier { } fn notify_error_diagnostics(&self, message: String) { self.out.notify(Notification::::new(ShowMessageParams { - typ: MessageType::Error, + typ: MessageType::ERROR, message, })); } fn notify_end_diagnostics(&self) { let mut params = self.progress_params.clone(); - params.done = Some(true); + params.value = ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd { + message: None, + })); self.out.notify(Notification::::new(params)); } } diff --git a/rls/src/actions/requests.rs b/rls/src/actions/requests.rs index 1391ee716a2..1e5bbea3ada 100644 --- a/rls/src/actions/requests.rs +++ b/rls/src/actions/requests.rs @@ -73,6 +73,7 @@ impl RequestAction for WorkspaceSymbol { .and_then(|id| analysis.get_def(id).ok()) .map(|parent| parent.name), deprecated: None, + tags: None, }) .collect()) } @@ -111,6 +112,7 @@ impl RequestAction for Symbols { .and_then(|id| analysis.get_def(id).ok()) .map(|parent| parent.name), deprecated: None, + tags: None, }) .collect()) } @@ -127,7 +129,7 @@ impl RequestAction for Hover { ctx: InitActionContext, params: Self::Params, ) -> Result { - let tooltip = hover::tooltip(&ctx, ¶ms)?; + let tooltip = hover::tooltip(&ctx, ¶ms.text_document_position_params)?; Ok(lsp_data::Hover { contents: HoverContents::Array(tooltip.contents), @@ -147,8 +149,12 @@ impl RequestAction for Implementation { ctx: InitActionContext, params: Self::Params, ) -> Result { - let file_path = parse_file_path!(¶ms.text_document.uri, "find_impls")?; - let span = ctx.convert_pos_to_span(file_path, params.position); + let file_path = parse_file_path!( + ¶ms.text_document_position_params.text_document.uri, + "find_impls" + )?; + let span = + ctx.convert_pos_to_span(file_path, params.text_document_position_params.position); let analysis = ctx.analysis; let type_id = analysis.id(&span).map_err(|_| ResponseError::Empty)?; @@ -179,8 +185,10 @@ impl RequestAction for Definition { params: Self::Params, ) -> Result { // Save-analysis thread. - let file_path = parse_file_path!(¶ms.text_document.uri, "goto_def")?; - let span = ctx.convert_pos_to_span(file_path.clone(), params.position); + let file_path = + parse_file_path!(¶ms.text_document_position_params.text_document.uri, "goto_def")?; + let span = ctx + .convert_pos_to_span(file_path.clone(), params.text_document_position_params.position); if let Ok(out) = ctx.analysis.goto_def(&span) { let result = vec![ls_util::rls_to_location(&out)]; @@ -194,7 +202,7 @@ impl RequestAction for Definition { if racer_enabled { let cache = ctx.racer_cache(); let session = ctx.racer_session(&cache); - let location = pos_to_racer_location(params.position); + let location = pos_to_racer_location(params.text_document_position_params.position); let r = racer::find_definition(file_path, location, &session) .and_then(|rm| location_from_racer_match(&rm)) @@ -272,7 +280,7 @@ impl RequestAction for Completion { let snippet = racer::snippet_for_match(&comp, &session); if !snippet.is_empty() { item.insert_text = Some(snippet); - item.insert_text_format = Some(InsertTextFormat::Snippet); + item.insert_text_format = Some(InsertTextFormat::SNIPPET); } } item @@ -292,8 +300,10 @@ impl RequestAction for DocumentHighlight { ctx: InitActionContext, params: Self::Params, ) -> Result { - let file_path = parse_file_path!(¶ms.text_document.uri, "highlight")?; - let span = ctx.convert_pos_to_span(file_path.clone(), params.position); + let file_path = + parse_file_path!(¶ms.text_document_position_params.text_document.uri, "highlight")?; + let span = ctx + .convert_pos_to_span(file_path.clone(), params.text_document_position_params.position); let result = ctx.analysis.find_all_refs(&span, true, false).unwrap_or_else(|_| vec![]); @@ -303,7 +313,7 @@ impl RequestAction for DocumentHighlight { if span.file == file_path { Some(lsp_data::DocumentHighlight { range: ls_util::rls_to_range(span.range), - kind: Some(DocumentHighlightKind::Text), + kind: Some(DocumentHighlightKind::TEXT), }) } else { None @@ -317,7 +327,11 @@ impl RequestAction for Rename { type Response = ResponseWithMessage; fn fallback_response() -> Result { - Ok(ResponseWithMessage::Response(WorkspaceEdit { changes: None, document_changes: None })) + Ok(ResponseWithMessage::Response(WorkspaceEdit { + changes: None, + document_changes: None, + change_annotations: None, + })) } fn handle( @@ -393,6 +407,7 @@ impl RequestAction for Rename { Ok(ResponseWithMessage::Response(WorkspaceEdit { changes: Some(edits), document_changes: None, + change_annotations: None, })) } } @@ -409,7 +424,7 @@ impl server::Response for ExecuteCommandResponse { match self { ExecuteCommandResponse::ApplyEdit(ref params) => { let id = out.provide_id(); - let params = ApplyWorkspaceEditParams { edit: params.edit.clone() }; + let params = ApplyWorkspaceEditParams { edit: params.edit.clone(), label: None }; let request = Request::::new(id, params); out.request(request); @@ -450,7 +465,7 @@ fn apply_suggestion(args: &[serde_json::Value]) -> Result = vec![(uri, text_edits)].into_iter().collect(); - let edit = WorkspaceEdit { changes: Some(changes), document_changes: None }; + let edit = + WorkspaceEdit { changes: Some(changes), document_changes: None, change_annotations: None }; if !ctx.quiescent.load(Ordering::SeqCst) { return Err(ResponseError::Empty); } - Ok(ApplyWorkspaceEditParams { edit }) + Ok(ApplyWorkspaceEditParams { edit, label: None }) } /// Creates `CodeAction`s for fixes suggested by the compiler. diff --git a/rls/src/cmd.rs b/rls/src/cmd.rs index 66b3a4ada31..cca66591bff 100644 --- a/rls/src/cmd.rs +++ b/rls/src/cmd.rs @@ -12,8 +12,9 @@ use std::sync::atomic::{AtomicU64, Ordering}; use lsp_types::{ ClientCapabilities, CodeActionContext, CodeActionParams, CompletionItem, DocumentFormattingParams, DocumentRangeFormattingParams, DocumentSymbolParams, - FormattingOptions, InitializeParams, Position, Range, RenameParams, TextDocumentIdentifier, - TextDocumentPositionParams, TraceOption, WindowClientCapabilities, WorkspaceSymbolParams, + FormattingOptions, GotoDefinitionParams, HoverParams, InitializeParams, PartialResultParams, + Position, Range, RenameParams, TextDocumentIdentifier, TextDocumentPositionParams, TraceOption, + WindowClientCapabilities, WorkDoneProgressParams, WorkspaceSymbolParams, }; use std::collections::HashMap; @@ -87,7 +88,7 @@ pub fn run() { } "format" => { let file_name = bits.next().expect("Expected file name"); - let tab_size: u64 = bits + let tab_size: u32 = bits .next() .unwrap_or("4") .parse() @@ -101,15 +102,15 @@ pub fn run() { } "range_format" => { let file_name = bits.next().expect("Expected file name"); - let start_row: u64 = + let start_row: u32 = bits.next().expect("Expected start line").parse().expect("Bad start line"); - let start_col: u64 = + let start_col: u32 = bits.next().expect("Expected start column").parse().expect("Bad start column"); - let end_row: u64 = + let end_row: u32 = bits.next().expect("Expected end line").parse().expect("Bad end line"); - let end_col: u64 = + let end_col: u32 = bits.next().expect("Expected end column").parse().expect("Bad end column"); - let tab_size: u64 = bits + let tab_size: u32 = bits .next() .unwrap_or("4") .parse() @@ -132,13 +133,13 @@ pub fn run() { } "code_action" => { let file_name = bits.next().expect("Expect file name"); - let start_row: u64 = + let start_row: u32 = bits.next().expect("Expect start line").parse().expect("Bad start line"); - let start_col: u64 = + let start_col: u32 = bits.next().expect("Expect start column").parse().expect("Bad start column"); - let end_row: u64 = + let end_row: u32 = bits.next().expect("Expect end line").parse().expect("Bad end line"); - let end_col: u64 = + let end_col: u32 = bits.next().expect("Expect end column").parse().expect("Bad end column"); code_action(file_name, start_row, start_col, end_row, end_col).to_string() } @@ -173,12 +174,16 @@ pub fn run() { } fn def(file_name: &str, row: &str, col: &str) -> Request { - let params = TextDocumentPositionParams { - text_document: TextDocumentIdentifier::new(url(file_name)), - position: Position::new( - u64::from_str(row).expect("Bad line number"), - u64::from_str(col).expect("Bad column number"), - ), + let params = GotoDefinitionParams { + text_document_position_params: TextDocumentPositionParams { + text_document: TextDocumentIdentifier::new(url(file_name)), + position: Position::new( + u32::from_str(row).expect("Bad line number"), + u32::from_str(col).expect("Bad column number"), + ), + }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }; Request { id: next_id(), params, received: Instant::now(), _action: PhantomData } } @@ -188,55 +193,74 @@ fn rename(file_name: &str, row: &str, col: &str, new_name: &str) -> Request Request { - let params = TextDocumentPositionParams { - text_document: TextDocumentIdentifier::new(url(file_name)), - position: Position::new( - u64::from_str(row).expect("Bad line number"), - u64::from_str(col).expect("Bad column number"), - ), + let params = HoverParams { + text_document_position_params: TextDocumentPositionParams { + text_document: TextDocumentIdentifier::new(url(file_name)), + position: Position::new( + u32::from_str(row).expect("Bad line number"), + u32::from_str(col).expect("Bad column number"), + ), + }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, }; Request { id: next_id(), params, received: Instant::now(), _action: PhantomData } } fn workspace_symbol(query: &str) -> Request { - let params = WorkspaceSymbolParams { query: query.to_owned() }; + let params = WorkspaceSymbolParams { + query: query.to_owned(), + partial_result_params: PartialResultParams { partial_result_token: None }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + }; Request { id: next_id(), params, received: Instant::now(), _action: PhantomData } } -fn format(file_name: &str, tab_size: u64, insert_spaces: bool) -> Request { +fn format(file_name: &str, tab_size: u32, insert_spaces: bool) -> Request { // no optional properties let properties = HashMap::default(); let params = DocumentFormattingParams { text_document: TextDocumentIdentifier::new(url(file_name)), - options: FormattingOptions { tab_size, insert_spaces, properties }, + options: FormattingOptions { + tab_size, + insert_spaces, + properties, + trim_trailing_whitespace: None, + insert_final_newline: None, + trim_final_newlines: None, + }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, }; Request { id: next_id(), params, received: Instant::now(), _action: PhantomData } } fn document_symbol(file_name: &str) -> Request { - let params = - DocumentSymbolParams { text_document: TextDocumentIdentifier::new(url(file_name)) }; + let params = DocumentSymbolParams { + text_document: TextDocumentIdentifier::new(url(file_name)), + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, + }; Request { id: next_id(), params, received: Instant::now(), _action: PhantomData } } fn range_format( file_name: &str, - start_row: u64, - start_col: u64, - end_row: u64, - end_col: u64, - tab_size: u64, + start_row: u32, + start_col: u32, + end_row: u32, + end_col: u32, + tab_size: u32, insert_spaces: bool, ) -> Request { // no optional properties @@ -248,17 +272,25 @@ fn range_format( start: Position::new(start_row, start_col), end: Position::new(end_row, end_col), }, - options: FormattingOptions { tab_size, insert_spaces, properties }, + options: FormattingOptions { + tab_size, + insert_spaces, + properties, + trim_trailing_whitespace: None, + insert_final_newline: None, + trim_final_newlines: None, + }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, }; Request { id: next_id(), params, received: Instant::now(), _action: PhantomData } } fn code_action( file_name: &str, - start_row: u64, - start_col: u64, - end_row: u64, - end_col: u64, + start_row: u32, + start_col: u32, + end_row: u32, + end_col: u32, ) -> Request { let params = CodeActionParams { text_document: TextDocumentIdentifier::new(url(file_name)), @@ -267,6 +299,8 @@ fn code_action( end: Position::new(end_row, end_col), }, context: CodeActionContext { diagnostics: Vec::new(), only: None }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }; Request { id: next_id(), params, received: Instant::now(), _action: PhantomData } } @@ -293,12 +327,20 @@ fn initialize(root_path: String) -> Request { initialization_options: None, capabilities: ClientCapabilities { workspace: None, - window: Some(WindowClientCapabilities { progress: Some(true) }), + window: Some(WindowClientCapabilities { + work_done_progress: Some(true), + show_message: None, + show_document: None, + }), text_document: None, experimental: None, + general: None, + offset_encoding: None, }, trace: Some(TraceOption::Off), workspace_folders: None, + client_info: None, + locale: None, }; Request { id: next_id(), params, received: Instant::now(), _action: PhantomData } } diff --git a/rls/src/lsp_data.rs b/rls/src/lsp_data.rs index fca64c09a03..8103e506dc2 100644 --- a/rls/src/lsp_data.rs +++ b/rls/src/lsp_data.rs @@ -54,7 +54,7 @@ pub fn make_workspace_edit(location: Location, new_text: String) -> WorkspaceEdi .into_iter() .collect(); - WorkspaceEdit { changes: Some(changes), document_changes: None } + WorkspaceEdit { changes: Some(changes), document_changes: None, change_annotations: None } } /// Utilities for working with the language server protocol. @@ -117,7 +117,7 @@ pub mod ls_util { if content.is_empty() { Range { start: Position::new(0, 0), end: Position::new(0, 0) } } else { - let mut line_count = content.lines().count() as u64 - 1; + let mut line_count = content.lines().count() - 1; let col = if content.ends_with('\n') { line_count += 1; 0 @@ -128,11 +128,11 @@ pub mod ls_util { .expect("String is not empty.") .chars() // LSP uses UTF-16 code units offset. - .map(|chr| chr.len_utf16() as u64) + .map(|chr| chr.len_utf16()) .sum() }; // Range is zero-based and end position is exclusive. - Range { start: Position::new(0, 0), end: Position::new(line_count, col) } + Range { start: Position::new(0, 0), end: Position::new(line_count as u32, col as u32) } } } } @@ -140,50 +140,50 @@ pub mod ls_util { /// Converts an RLS def-kind to a language server protocol symbol-kind. pub fn source_kind_from_def_kind(k: DefKind) -> SymbolKind { match k { - DefKind::Enum | DefKind::Union => SymbolKind::Enum, - DefKind::Static | DefKind::Const | DefKind::ForeignStatic => SymbolKind::Constant, - DefKind::Tuple => SymbolKind::Array, - DefKind::Struct => SymbolKind::Struct, - DefKind::Function | DefKind::Macro | DefKind::ForeignFunction => SymbolKind::Function, - DefKind::Method => SymbolKind::Method, - DefKind::Mod => SymbolKind::Module, - DefKind::Trait => SymbolKind::Interface, - DefKind::Type | DefKind::ExternType => SymbolKind::TypeParameter, - DefKind::Local => SymbolKind::Variable, - DefKind::Field => SymbolKind::Field, - DefKind::TupleVariant | DefKind::StructVariant => SymbolKind::EnumMember, + DefKind::Enum | DefKind::Union => SymbolKind::ENUM, + DefKind::Static | DefKind::Const | DefKind::ForeignStatic => SymbolKind::CONSTANT, + DefKind::Tuple => SymbolKind::ARRAY, + DefKind::Struct => SymbolKind::STRUCT, + DefKind::Function | DefKind::Macro | DefKind::ForeignFunction => SymbolKind::FUNCTION, + DefKind::Method => SymbolKind::METHOD, + DefKind::Mod => SymbolKind::MODULE, + DefKind::Trait => SymbolKind::INTERFACE, + DefKind::Type | DefKind::ExternType => SymbolKind::TYPE_PARAMETER, + DefKind::Local => SymbolKind::VARIABLE, + DefKind::Field => SymbolKind::FIELD, + DefKind::TupleVariant | DefKind::StructVariant => SymbolKind::ENUM_MEMBER, } } /// Indicates the kind of completion for this racer match type. pub fn completion_kind_from_match_type(m: racer::MatchType) -> CompletionItemKind { match m { - racer::MatchType::Crate | racer::MatchType::Module => CompletionItemKind::Module, - racer::MatchType::Struct(_) => CompletionItemKind::Struct, - racer::MatchType::Union(_) => CompletionItemKind::Struct, - racer::MatchType::Enum(_) => CompletionItemKind::Enum, + racer::MatchType::Crate | racer::MatchType::Module => CompletionItemKind::MODULE, + racer::MatchType::Struct(_) => CompletionItemKind::STRUCT, + racer::MatchType::Union(_) => CompletionItemKind::STRUCT, + racer::MatchType::Enum(_) => CompletionItemKind::ENUM, racer::MatchType::StructField | racer::MatchType::EnumVariant(_) => { - CompletionItemKind::Field + CompletionItemKind::FIELD } racer::MatchType::Macro | racer::MatchType::Function | racer::MatchType::Method(_) - | racer::MatchType::FnArg(_) => CompletionItemKind::Function, - racer::MatchType::Type | racer::MatchType::Trait => CompletionItemKind::Interface, + | racer::MatchType::FnArg(_) => CompletionItemKind::FUNCTION, + racer::MatchType::Type | racer::MatchType::Trait => CompletionItemKind::INTERFACE, racer::MatchType::Let(_) | racer::MatchType::IfLet(_) | racer::MatchType::WhileLet(_) | racer::MatchType::For(_) | racer::MatchType::MatchArm | racer::MatchType::Const - | racer::MatchType::Static => CompletionItemKind::Variable, - racer::MatchType::TypeParameter(_) => CompletionItemKind::TypeParameter, - racer::MatchType::Builtin(_) => CompletionItemKind::Keyword, + | racer::MatchType::Static => CompletionItemKind::VARIABLE, + racer::MatchType::TypeParameter(_) => CompletionItemKind::TYPE_PARAMETER, + racer::MatchType::Builtin(_) => CompletionItemKind::KEYWORD, racer::MatchType::UseAlias(m) => match m.mtype { racer::MatchType::UseAlias(_) => unreachable!("Nested use aliases"), typ => completion_kind_from_match_type(typ), }, - racer::MatchType::AssocType => CompletionItemKind::TypeParameter, + racer::MatchType::AssocType => CompletionItemKind::TYPE_PARAMETER, } } diff --git a/rls/src/server/message.rs b/rls/src/server/message.rs index e7fef3f6a6a..bd8d0247040 100644 --- a/rls/src/server/message.rs +++ b/rls/src/server/message.rs @@ -74,7 +74,7 @@ impl Response for ResponseWithMessage { ResponseWithMessage::Response(r) => out.success(id, &r), ResponseWithMessage::Warn(s) => { out.notify(Notification::::new(ShowMessageParams { - typ: MessageType::Warning, + typ: MessageType::WARNING, message: s, })); @@ -87,7 +87,7 @@ impl Response for ResponseWithMessage { impl DefaultResponse for WorkspaceEdit { fn default() -> WorkspaceEdit { - WorkspaceEdit { changes: None, document_changes: None } + WorkspaceEdit { changes: None, document_changes: None, change_annotations: None } } } @@ -482,7 +482,7 @@ mod test { fn serialize_message_empty_params() { #[derive(Debug)] enum DummyNotification {} - #[derive(Serialize)] + #[derive(Serialize, Deserialize)] struct EmptyParams {} impl LSPNotification for DummyNotification { diff --git a/rls/src/server/mod.rs b/rls/src/server/mod.rs index 5e3efe86baf..7aa2eab87ba 100644 --- a/rls/src/server/mod.rs +++ b/rls/src/server/mod.rs @@ -25,8 +25,9 @@ pub use lsp_types::request::Initialize as InitializeRequest; pub use lsp_types::request::Shutdown as ShutdownRequest; use lsp_types::{ CodeActionProviderCapability, CodeLensOptions, CompletionOptions, ExecuteCommandOptions, - ImplementationProviderCapability, InitializeParams, InitializeResult, RenameProviderCapability, - ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind, + HoverProviderCapability, ImplementationProviderCapability, InitializeParams, InitializeResult, + OneOf, ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind, + WorkDoneProgressOptions, }; use rls_analysis::AnalysisHost; use rls_vfs::Vfs; @@ -89,7 +90,7 @@ pub(crate) fn maybe_notify_unknown_configs(out: &O, unknowns: &[Strin first = false; } out.notify(Notification::::new(ShowMessageParams { - typ: MessageType::Warning, + typ: MessageType::WARNING, message: msg, })); } @@ -106,7 +107,7 @@ pub(crate) fn maybe_notify_deprecated_configs(out: &O, keys: &[String ); out.notify(Notification::::new(ShowMessageParams { - typ: MessageType::Warning, + typ: MessageType::WARNING, message, })); } @@ -131,7 +132,7 @@ pub(crate) fn maybe_notify_duplicated_configs( msg += "; "; } out.notify(Notification::::new(ShowMessageParams { - typ: MessageType::Warning, + typ: MessageType::WARNING, message: format!("Duplicated RLS configuration: {}", msg), })); } @@ -191,7 +192,11 @@ impl BlockingRequestAction for InitializeRequest { maybe_notify_deprecated_configs(&out, &deprecated); maybe_notify_duplicated_configs(&out, &dups); - let result = InitializeResult { capabilities: server_caps(ctx) }; + let result = InitializeResult { + capabilities: server_caps(ctx), + server_info: None, + offset_encoding: None, + }; // Send response early before `ctx.init` to enforce // initialize-response-before-all-other-messages constraint. @@ -435,22 +440,25 @@ pub enum ServerStateChange { fn server_caps(ctx: &ActionContext) -> ServerCapabilities { ServerCapabilities { text_document_sync: Some(TextDocumentSyncCapability::Kind( - TextDocumentSyncKind::Incremental, + TextDocumentSyncKind::INCREMENTAL, )), - hover_provider: Some(true), + hover_provider: Some(HoverProviderCapability::Simple(true)), completion_provider: Some(CompletionOptions { resolve_provider: Some(true), trigger_characters: Some(vec![".".to_string(), ":".to_string()]), + all_commit_characters: None, + work_done_progress_options: WorkDoneProgressOptions { work_done_progress: Some(false) }, + completion_item: None, }), - definition_provider: Some(true), + definition_provider: Some(OneOf::Left(true)), type_definition_provider: None, implementation_provider: Some(ImplementationProviderCapability::Simple(true)), - references_provider: Some(true), - document_highlight_provider: Some(true), - document_symbol_provider: Some(true), - workspace_symbol_provider: Some(true), + references_provider: Some(OneOf::Left(true)), + document_highlight_provider: Some(OneOf::Left(true)), + document_symbol_provider: Some(OneOf::Left(true)), + workspace_symbol_provider: Some(OneOf::Left(true)), code_action_provider: Some(CodeActionProviderCapability::Simple(true)), - document_formatting_provider: Some(true), + document_formatting_provider: Some(OneOf::Left(true)), execute_command_provider: Some(ExecuteCommandOptions { // We append our pid to the command so that if there are multiple // instances of the RLS then they will have unique names for the @@ -459,14 +467,15 @@ fn server_caps(ctx: &ActionContext) -> ServerCapabilities { format!("rls.applySuggestion-{}", ctx.pid()), format!("rls.deglobImports-{}", ctx.pid()), ], + work_done_progress_options: WorkDoneProgressOptions { work_done_progress: Some(false) }, }), - rename_provider: Some(RenameProviderCapability::Simple(true)), + rename_provider: Some(OneOf::Left(true)), color_provider: None, // These are supported if the `unstable_features` option is set. // We'll update these capabilities dynamically when we get config // info from the client. - document_range_formatting_provider: Some(false), + document_range_formatting_provider: Some(OneOf::Left(false)), code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(false) }), document_on_type_formatting_provider: None, @@ -475,6 +484,13 @@ fn server_caps(ctx: &ActionContext) -> ServerCapabilities { folding_range_provider: None, workspace: None, selection_range_provider: None, + document_link_provider: None, + declaration_provider: None, + call_hierarchy_provider: None, + semantic_tokens_provider: None, + moniker_provider: None, + linked_editing_range_provider: None, + experimental: None, } } @@ -507,9 +523,13 @@ mod test { window: None, text_document: None, experimental: None, + general: None, + offset_encoding: None, }, trace: Some(lsp_types::TraceOption::Off), workspace_folders: None, + client_info: None, + locale: None, } } diff --git a/tests/client.rs b/tests/client.rs index 20262dd5165..77db73e4259 100644 --- a/tests/client.rs +++ b/tests/client.rs @@ -21,12 +21,20 @@ fn initialize_params(root_path: &Path) -> InitializeParams { initialization_options: None, capabilities: ClientCapabilities { workspace: None, - window: Some(WindowClientCapabilities { progress: Some(true) }), + window: Some(WindowClientCapabilities { + work_done_progress: Some(true), + show_message: None, + show_document: None, + }), text_document: None, experimental: None, + general: None, + offset_encoding: None, }, trace: None, workspace_folders: None, + client_info: None, + locale: None, } } @@ -263,7 +271,7 @@ fn client_changing_workspace_lib_retains_diagnostics() { }], text_document: VersionedTextDocumentIdentifier { uri: Url::from_file_path(p.root().join("library/src/lib.rs")).unwrap(), - version: Some(0), + version: 0, }, }); @@ -289,7 +297,7 @@ fn client_changing_workspace_lib_retains_diagnostics() { }], text_document: VersionedTextDocumentIdentifier { uri: Url::from_file_path(p.root().join("library/src/lib.rs")).unwrap(), - version: Some(1), + version: 1, }, }); @@ -366,7 +374,7 @@ fn client_implicit_workspace_pick_up_lib_changes() { }], text_document: VersionedTextDocumentIdentifier { uri: Url::from_file_path(p.root().join("inner/src/lib.rs")).unwrap(), - version: Some(0), + version: 0, }, }); @@ -387,7 +395,7 @@ fn client_implicit_workspace_pick_up_lib_changes() { }], text_document: VersionedTextDocumentIdentifier { uri: Url::from_file_path(p.root().join("inner/src/lib.rs")).unwrap(), - version: Some(1), + version: 1, }, }); @@ -444,7 +452,7 @@ fn client_test_complete_self_crate_name() { CompletionParams { context: Some(CompletionContext { trigger_character: Some(":".to_string()), - trigger_kind: CompletionTriggerKind::TriggerCharacter, + trigger_kind: CompletionTriggerKind::TRIGGER_CHARACTER, }), text_document_position: TextDocumentPositionParams { position: Position::new(2, 32), @@ -452,6 +460,8 @@ fn client_test_complete_self_crate_name() { uri: Url::from_file_path(p.root().join("library/tests/test.rs")).unwrap(), }, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); @@ -518,21 +528,29 @@ fn client_completion_suggests_arguments_in_statements() { initialization_options: None, capabilities: lsp_types::ClientCapabilities { workspace: None, - window: Some(WindowClientCapabilities { progress: Some(true) }), + window: Some(WindowClientCapabilities { + work_done_progress: Some(true), + show_message: None, + show_document: None, + }), text_document: Some(TextDocumentClientCapabilities { - completion: Some(CompletionCapability { + completion: Some(CompletionClientCapabilities { completion_item: Some(CompletionItemCapability { snippet_support: Some(true), ..CompletionItemCapability::default() }), - ..CompletionCapability::default() + ..CompletionClientCapabilities::default() }), ..TextDocumentClientCapabilities::default() }), experimental: None, + general: None, + offset_encoding: None, }, trace: None, workspace_folders: None, + client_info: None, + locale: None, }, ); @@ -544,7 +562,7 @@ fn client_completion_suggests_arguments_in_statements() { CompletionParams { context: Some(CompletionContext { trigger_character: Some("f".to_string()), - trigger_kind: CompletionTriggerKind::TriggerCharacter, + trigger_kind: CompletionTriggerKind::TRIGGER_CHARACTER, }), text_document_position: TextDocumentPositionParams { position: Position::new(3, 41), @@ -552,6 +570,8 @@ fn client_completion_suggests_arguments_in_statements() { uri: Url::from_file_path(p.root().join("library/tests/test.rs")).unwrap(), }, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); @@ -612,7 +632,7 @@ fn client_use_statement_completion_doesnt_suggest_arguments() { CompletionParams { context: Some(CompletionContext { trigger_character: Some(":".to_string()), - trigger_kind: CompletionTriggerKind::TriggerCharacter, + trigger_kind: CompletionTriggerKind::TRIGGER_CHARACTER, }), text_document_position: TextDocumentPositionParams { position: Position::new(2, 32), @@ -620,6 +640,8 @@ fn client_use_statement_completion_doesnt_suggest_arguments() { uri: Url::from_file_path(p.root().join("library/tests/test.rs")).unwrap(), }, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); @@ -678,7 +700,7 @@ fn client_dependency_typo_and_fix() { let diag = rls.wait_for_diagnostics(); assert_eq!(diag.diagnostics.len(), 1); - assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::Error)); + assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::ERROR)); assert!(diag.diagnostics[0] .message .contains("no matching package found\nsearched package name: `auto-cfg`")); @@ -692,13 +714,13 @@ fn client_dependency_typo_and_fix() { rls.notify::(DidChangeWatchedFilesParams { changes: vec![FileEvent { uri: Url::from_file_path(p.root().join("Cargo.toml")).unwrap(), - typ: FileChangeType::Changed, + typ: FileChangeType::CHANGED, }], }); let diag = rls.wait_for_diagnostics(); assert_eq!(diag.diagnostics.len(), 1); - assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::Error)); + assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::ERROR)); assert!(diag.diagnostics[0].message.contains("^0.5555")); // Fix version issue so no error diagnostics occur. @@ -708,13 +730,13 @@ fn client_dependency_typo_and_fix() { rls.notify::(DidChangeWatchedFilesParams { changes: vec![FileEvent { uri: Url::from_file_path(p.root().join("Cargo.toml")).unwrap(), - typ: FileChangeType::Changed, + typ: FileChangeType::CHANGED, }], }); let diag = rls.wait_for_diagnostics(); assert_eq!( - diag.diagnostics.iter().find(|d| d.severity == Some(DiagnosticSeverity::Error)), + diag.diagnostics.iter().find(|d| d.severity == Some(DiagnosticSeverity::ERROR)), None ); } @@ -749,7 +771,7 @@ fn client_invalid_toml_manifest() { assert!(diag.uri.as_str().ends_with("invalid_toml/Cargo.toml")); assert_eq!(diag.diagnostics.len(), 1); - assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::Error)); + assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::ERROR)); assert!(diag.diagnostics[0].message.contains("failed to parse manifest")); assert_eq!( @@ -814,7 +836,7 @@ fn client_invalid_member_toml_manifest() { assert!(diag.uri.as_str().ends_with("invalid_member_toml/member_a/dodgy_member/Cargo.toml")); assert_eq!(diag.diagnostics.len(), 1); - assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::Error)); + assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::ERROR)); assert!(diag.diagnostics[0].message.contains("failed to load manifest")); } @@ -873,7 +895,7 @@ fn client_invalid_member_dependency_resolution() { .ends_with("invalid_member_resolution/member_a/dodgy_member/Cargo.toml")); assert_eq!(diag.diagnostics.len(), 1); - assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::Error)); + assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::ERROR)); assert!(diag.diagnostics[0].message.contains("no matching package named `nosuchdep123`")); } @@ -901,7 +923,7 @@ fn client_handle_utf16_unit_text_edits() { rls.notify::(DidChangeTextDocumentParams { text_document: VersionedTextDocumentIdentifier { uri: Url::from_file_path(p.root().join("src/some.rs")).unwrap(), - version: Some(0), + version: 0, }, // "😢" -> "" content_changes: vec![TextDocumentContentChangeEvent { @@ -947,7 +969,11 @@ fn client_format_utf16_range() { tab_size: 4, insert_spaces: true, properties: Default::default(), + trim_trailing_whitespace: None, + insert_final_newline: None, + trim_final_newlines: None, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, }, ); @@ -974,6 +1000,8 @@ fn client_lens_run() { capabilities: Default::default(), trace: None, workspace_folders: None, + client_info: None, + locale: None, }, ); @@ -986,6 +1014,8 @@ fn client_lens_run() { text_document: TextDocumentIdentifier { uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); @@ -1064,11 +1094,15 @@ fn client_find_definitions() { let id = (line_index * 100 + i) as u64; let result = rls.request::( id, - TextDocumentPositionParams { - position: Position { line: line_index as u64, character: i as u64 }, - text_document: TextDocumentIdentifier { - uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + GotoDefinitionParams { + text_document_position_params: TextDocumentPositionParams { + position: Position { line: line_index as u32, character: i as u32 }, + text_document: TextDocumentIdentifier { + uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + }, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); @@ -1179,6 +1213,8 @@ fn client_deglob() { }, range: Range { start: Position::new(2, 0), end: Position::new(2, 0) }, context: CodeActionContext { diagnostics: vec![], only: None }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ) .expect("No code actions returned for line 2"); @@ -1205,7 +1241,14 @@ fn client_deglob() { } ); - rls.request::(200, ExecuteCommandParams { command, arguments }); + rls.request::( + 200, + ExecuteCommandParams { + command, + arguments, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + }, + ); // Right now the execute command returns an empty response and sends // appropriate apply edit request via a side-channel let result = rls @@ -1237,6 +1280,8 @@ fn client_deglob() { }, range: Range { start: Position::new(5, 0), end: Position::new(5, 0) }, context: CodeActionContext { diagnostics: vec![], only: None }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ) .expect("No code actions returned for line 12"); @@ -1268,7 +1313,14 @@ fn client_deglob() { ); } - rls.request::(1200, ExecuteCommandParams { command, arguments }); + rls.request::( + 1200, + ExecuteCommandParams { + command, + arguments, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + }, + ); // Right now the execute command returns an empty response and sends // appropriate apply edit request via a side-channel let result = rls @@ -1417,11 +1469,15 @@ fn client_goto_def() { let result = rls.request::( 11, - TextDocumentPositionParams { - position: Position { line: 12, character: 27 }, - text_document: TextDocumentIdentifier { - uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + GotoDefinitionParams { + text_document_position_params: TextDocumentPositionParams { + position: Position { line: 12, character: 27 }, + text_document: TextDocumentIdentifier { + uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + }, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); @@ -1453,11 +1509,14 @@ fn client_hover() { let result = rls .request::( 11, - TextDocumentPositionParams { - position: Position { line: 12, character: 27 }, - text_document: TextDocumentIdentifier { - uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + HoverParams { + text_document_position_params: TextDocumentPositionParams { + position: Position { line: 12, character: 27 }, + text_document: TextDocumentIdentifier { + uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + }, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, }, ) .unwrap(); @@ -1490,11 +1549,14 @@ fn client_hover_after_src_line_change() { let result = rls .request::( 11, - TextDocumentPositionParams { - position: world_src_pos, - text_document: TextDocumentIdentifier { - uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + HoverParams { + text_document_position_params: TextDocumentPositionParams { + position: world_src_pos, + text_document: TextDocumentIdentifier { + uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + }, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, }, ) .unwrap(); @@ -1519,7 +1581,7 @@ fn client_hover_after_src_line_change() { }], text_document: VersionedTextDocumentIdentifier { uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), - version: Some(2), + version: 2, }, }); @@ -1528,11 +1590,14 @@ fn client_hover_after_src_line_change() { let result = rls .request::( 11, - TextDocumentPositionParams { - position: world_src_pos_after, - text_document: TextDocumentIdentifier { - uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + HoverParams { + text_document_position_params: TextDocumentPositionParams { + position: world_src_pos_after, + text_document: TextDocumentIdentifier { + uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + }, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, }, ) .unwrap(); @@ -1553,12 +1618,19 @@ fn client_workspace_symbol() { rls.wait_for_indexing(); let symbols = rls - .request::(42, WorkspaceSymbolParams { query: "nemo".to_owned() }) + .request::( + 42, + WorkspaceSymbolParams { + query: "nemo".to_owned(), + partial_result_params: PartialResultParams { partial_result_token: None }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + }, + ) .unwrap(); let mut nemos = vec![ - ("src/main.rs", "nemo", SymbolKind::Function, 1, 11, 1, 15, Some("x")), - ("src/foo.rs", "nemo", SymbolKind::Module, 0, 4, 0, 8, Some("foo")), + ("src/main.rs", "nemo", SymbolKind::FUNCTION, 1, 11, 1, 15, Some("x")), + ("src/foo.rs", "nemo", SymbolKind::MODULE, 0, 4, 0, 8, Some("foo")), ]; for (file, name, kind, start_l, start_c, end_l, end_c, container_name) in nemos.drain(..) { @@ -1574,6 +1646,7 @@ fn client_workspace_symbol() { }, }, deprecated: None, + tags: None, }; dbg!(&sym); assert!(symbols.iter().any(|s| *s == sym)); @@ -1594,12 +1667,19 @@ fn client_workspace_symbol_duplicates() { rls.wait_for_indexing(); let symbols = rls - .request::(42, WorkspaceSymbolParams { query: "Frobnicator".to_owned() }) + .request::( + 42, + WorkspaceSymbolParams { + query: "Frobnicator".to_owned(), + partial_result_params: PartialResultParams { partial_result_token: None }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + }, + ) .unwrap(); let symbol = SymbolInformation { name: "Frobnicator".to_string(), - kind: SymbolKind::Struct, + kind: SymbolKind::STRUCT, container_name: Some("a".to_string()), location: Location { uri: Url::from_file_path(p.root().join("src/shared.rs")).unwrap(), @@ -1609,6 +1689,7 @@ fn client_workspace_symbol_duplicates() { }, }, deprecated: None, + tags: None, }; assert_eq!(symbols, vec![symbol]); @@ -1637,6 +1718,8 @@ fn client_find_all_refs_test() { position: Position { line: 0, character: 7 }, }, context: ReferenceContext { include_declaration: true }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ) .unwrap(); @@ -1677,6 +1760,8 @@ fn client_find_all_refs_no_cfg_test() { position: Position { line: 0, character: 7 }, }, context: ReferenceContext { include_declaration: true }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ) .unwrap(); @@ -1722,11 +1807,15 @@ fn client_highlight() { let result = rls .request::( 42, - TextDocumentPositionParams { - position: Position { line: 12, character: 27 }, - text_document: TextDocumentIdentifier { - uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + DocumentHighlightParams { + text_document_position_params: TextDocumentPositionParams { + position: Position { line: 12, character: 27 }, + text_document: TextDocumentIdentifier { + uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + }, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ) .unwrap(); @@ -1766,6 +1855,7 @@ fn client_rename() { }, }, new_name: "foo".to_owned(), + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, }, ) .unwrap(); @@ -1807,7 +1897,11 @@ fn client_reformat() { tab_size: 4, insert_spaces: true, properties: Default::default(), + trim_trailing_whitespace: None, + insert_final_newline: None, + trim_final_newlines: None, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, }, ); @@ -1846,7 +1940,11 @@ fn client_reformat_with_range() { tab_size: 4, insert_spaces: true, properties: Default::default(), + trim_trailing_whitespace: None, + insert_final_newline: None, + trim_final_newlines: None, }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, }, ); @@ -1919,8 +2017,8 @@ fn client_completion() { let expected = [ // FIXME(https://github.com/rust-lang/rls/issues/1205) - empty " " string - ("world", &Some(CompletionItemKind::Variable), &Some("let world = \" \";".to_string())), - ("x", &Some(CompletionItemKind::Field), &Some("x: u64".to_string())), + ("world", &Some(CompletionItemKind::VARIABLE), &Some("let world = \" \";".to_string())), + ("x", &Some(CompletionItemKind::FIELD), &Some("x: u64".to_string())), ]; let result = rls.request::( @@ -1931,6 +2029,8 @@ fn client_completion() { position: Position { line: 12, character: 30 }, }, context: None, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); let items = completions(result.unwrap()); @@ -1943,6 +2043,8 @@ fn client_completion() { position: Position { line: 15, character: 30 }, }, context: None, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); let items = completions(result.unwrap()); @@ -1962,7 +2064,7 @@ fn client_bin_lib_project() { assert!(diag.uri.as_str().ends_with("bin_lib/tests/tests.rs")); assert_eq!(diag.diagnostics.len(), 1); - assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::Warning)); + assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::WARNING)); assert!(diag.diagnostics[0].message.contains("unused variable: `unused_var`")); } @@ -1978,7 +2080,7 @@ fn client_infer_lib() { assert!(diag.uri.as_str().ends_with("src/lib.rs")); assert_eq!(diag.diagnostics.len(), 1); - assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::Warning)); + assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::WARNING)); assert!(diag.diagnostics[0].message.contains("struct `UnusedLib` is never constructed")); } @@ -2024,9 +2126,13 @@ fn client_find_impls() { let result = rls.request::( 1, - TextDocumentPositionParams { - text_document: TextDocumentIdentifier::new(uri.clone()), - position: Position { line: 3, character: 7 }, // "Bar" + GotoDefinitionParams { + text_document_position_params: TextDocumentPositionParams { + text_document: TextDocumentIdentifier::new(uri.clone()), + position: Position { line: 3, character: 7 }, // "Bar" + }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); let expected = [(9, 15, 9, 18), (10, 12, 10, 15)]; @@ -2044,9 +2150,13 @@ fn client_find_impls() { let result = rls.request::( 1, - TextDocumentPositionParams { - text_document: TextDocumentIdentifier::new(uri.clone()), - position: Position { line: 6, character: 6 }, // "Super" + GotoDefinitionParams { + text_document_position_params: TextDocumentPositionParams { + text_document: TextDocumentIdentifier::new(uri.clone()), + position: Position { line: 6, character: 6 }, // "Super" + }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); let expected = [(9, 15, 9, 18), (13, 15, 13, 18)]; @@ -2075,7 +2185,7 @@ fn client_features() { let diag = rls.wait_for_diagnostics(); assert_eq!(diag.diagnostics.len(), 1); - assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::Error)); + assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::ERROR)); let msg = "cannot find struct, variant or union type `Foo` in this scope"; assert!(diag.diagnostics[0].message.contains(msg)); } @@ -2110,9 +2220,9 @@ fn client_no_default_features() { let diag = rls.wait_for_diagnostics(); let diagnostics: Vec<_> = - diag.diagnostics.iter().filter(|d| d.severity == Some(DiagnosticSeverity::Error)).collect(); + diag.diagnostics.iter().filter(|d| d.severity == Some(DiagnosticSeverity::ERROR)).collect(); assert_eq!(diagnostics.len(), 1); - assert_eq!(diagnostics[0].severity, Some(DiagnosticSeverity::Error)); + assert_eq!(diagnostics[0].severity, Some(DiagnosticSeverity::ERROR)); let msg = "cannot find struct, variant or union type `Baz` in this scope"; assert!(diagnostics[0].message.contains(msg)); } @@ -2130,7 +2240,7 @@ fn client_all_targets() { assert!(diag.uri.as_str().ends_with("bin_lib/tests/tests.rs")); assert_eq!(diag.diagnostics.len(), 1); - assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::Warning)); + assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::WARNING)); assert!(diag.diagnostics[0].message.contains("unused variable: `unused_var`")); } @@ -2159,11 +2269,15 @@ fn client_fail_uninitialized_request() { rls.request::( ID, - TextDocumentPositionParams { - text_document: TextDocumentIdentifier { - uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + GotoDefinitionParams { + text_document_position_params: TextDocumentPositionParams { + text_document: TextDocumentIdentifier { + uri: Url::from_file_path(p.root().join("src/main.rs")).unwrap(), + }, + position: Position { line: 0, character: 0 }, }, - position: Position { line: 0, character: 0 }, + work_done_progress_params: WorkDoneProgressParams { work_done_token: None }, + partial_result_params: PartialResultParams { partial_result_token: None }, }, ); @@ -2204,7 +2318,7 @@ fn client_init_impl(convert_case: fn(&str) -> String) { let diag = rls.wait_for_diagnostics(); assert_eq!(diag.diagnostics.len(), 1); - assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::Error)); + assert_eq!(diag.diagnostics[0].severity, Some(DiagnosticSeverity::ERROR)); let msg = "cannot find type `PathBuf` in this scope"; assert!(diag.diagnostics[0].message.contains(msg)); } diff --git a/tests/support/harness.rs b/tests/support/harness.rs index 291b6faea1b..81df3e501ec 100644 --- a/tests/support/harness.rs +++ b/tests/support/harness.rs @@ -287,13 +287,13 @@ impl Cache { pub(crate) fn mk_ls_position(&mut self, src: Src<'_>) -> lsp_types::Position { let line = self.get_line(src); let col = line.find(src.name).expect(&format!("Line does not contain name {}", src.name)); - lsp_types::Position::new((src.line - 1) as u64, char_of_byte_index(&line, col) as u64) + lsp_types::Position::new((src.line - 1) as u32, char_of_byte_index(&line, col) as u32) } /// Create a range covering the initial position on the line /// /// The line number uses a 0-based index. - pub(crate) fn mk_ls_range_from_line(&mut self, line: u64) -> lsp_types::Range { + pub(crate) fn mk_ls_range_from_line(&mut self, line: u32) -> lsp_types::Range { lsp_types::Range::new(lsp_types::Position::new(line, 0), lsp_types::Position::new(line, 0)) } diff --git a/tests/tooltip.rs b/tests/tooltip.rs index 520ea14e9aa..947efc48795 100644 --- a/tests/tooltip.rs +++ b/tests/tooltip.rs @@ -26,9 +26,9 @@ pub struct Test { /// Relative to the project _source_ dir (e.g. relative to $FIXTURES_DIR/hover/src) pub file: String, /// One-based line number - pub line: u64, + pub line: u32, /// One-based column number - pub col: u64, + pub col: u32, } impl Test { @@ -75,7 +75,7 @@ impl TestResult { } impl Test { - pub fn new(file: &str, line: u64, col: u64) -> Test { + pub fn new(file: &str, line: u32, col: u32) -> Test { Test { file: file.into(), line, col } } @@ -86,7 +86,7 @@ impl Test { fn run(&self, project_dir: &Path, ctx: &InitActionContext) -> TestResult { let url = Url::from_file_path(project_dir.join("src").join(&self.file)).expect(&self.file); let doc_id = TextDocumentIdentifier::new(url); - let position = Position::new(self.line - 1u64, self.col - 1u64); + let position = Position::new(self.line - 1, self.col - 1); let params = TextDocumentPositionParams::new(doc_id, position); let result = tooltip(&ctx, ¶ms) .map_err(|e| format!("tooltip error: {:?}", e)) From fe6a2ad0ba04b1e4983cd5ed418a63372a302f86 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sat, 12 Mar 2022 05:27:05 -0800 Subject: [PATCH 2/3] test: fix the progress tests --- tests/client.rs | 9 ++++++--- tests/support/client/mod.rs | 4 +--- tests/support/mod.rs | 5 +---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/client.rs b/tests/client.rs index 77db73e4259..505f60502c3 100644 --- a/tests/client.rs +++ b/tests/client.rs @@ -175,10 +175,13 @@ fn client_test_simple_workspace() { let count = rls .messages() .iter() - .filter(|msg| msg["method"] == "window/progress") - .filter(|msg| msg["params"]["title"] == "Building") + .filter(|msg| msg["method"] == "$/progress") + .filter(|msg| msg["params"]["value"]["kind"] == "report") .filter(|msg| { - msg["params"]["message"].as_str().map(|x| x.starts_with("member_")).unwrap_or(false) + msg["params"]["value"]["message"] + .as_str() + .map(|x| x.starts_with("member_")) + .unwrap_or(false) }) .count(); assert_eq!(count, 4); diff --git a/tests/support/client/mod.rs b/tests/support/client/mod.rs index cee9eec6ee3..17fd771f6e7 100644 --- a/tests/support/client/mod.rs +++ b/tests/support/client/mod.rs @@ -265,9 +265,7 @@ impl RlsHandle { /// Blocks until the processing (building + indexing) is done by the RLS. #[allow(clippy::bool_comparison)] pub fn wait_for_indexing(&mut self) { - self.wait_for_message(|msg| { - msg["params"]["title"] == "Indexing" && msg["params"]["done"] == true - }); + self.wait_for_message(|msg| msg["params"]["value"]["kind"] == "end"); } /// Blocks until a "textDocument/publishDiagnostics" message is received. diff --git a/tests/support/mod.rs b/tests/support/mod.rs index 6064100d324..772e1e4fafa 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -179,10 +179,7 @@ impl RlsHandle { |stdout| { stdout .to_json_messages() - .filter(|json| { - json["params"]["title"] == "Indexing" - && json["params"]["done"].as_bool().unwrap_or(false) - }) + .filter(|json| json["params"]["value"]["kind"] == "end") .count() >= n }, From e6ef17b361b89e6d3648289447d02fbd3b28559d Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Sat, 30 Apr 2022 22:44:25 -0700 Subject: [PATCH 3/3] test: add missing main functions to fixtures --- tests/fixtures/find_impls/src/main.rs | 2 ++ tests/fixtures/workspace_symbol_duplicates/src/main.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/fixtures/find_impls/src/main.rs b/tests/fixtures/find_impls/src/main.rs index 0812b576a19..94b07d05f88 100644 --- a/tests/fixtures/find_impls/src/main.rs +++ b/tests/fixtures/find_impls/src/main.rs @@ -12,3 +12,5 @@ impl Eq for Bar {} impl Sub for Foo {} impl Super for Foo {} + +fn main() {} \ No newline at end of file diff --git a/tests/fixtures/workspace_symbol_duplicates/src/main.rs b/tests/fixtures/workspace_symbol_duplicates/src/main.rs index fc450be19d0..de7b268512c 100644 --- a/tests/fixtures/workspace_symbol_duplicates/src/main.rs +++ b/tests/fixtures/workspace_symbol_duplicates/src/main.rs @@ -2,3 +2,5 @@ mod a; #[path="shared.rs"] mod b; + +fn main() {} \ No newline at end of file