diff --git a/server/src/diagnostic_ext.rs b/server/src/diagnostic_ext.rs index 4569803..a4ae389 100644 --- a/server/src/diagnostic_ext.rs +++ b/server/src/diagnostic_ext.rs @@ -1,14 +1,12 @@ // Copyright (c) ZeroC, Inc. use crate::configuration_set::ConfigurationSet; -use crate::utils::convert_slice_path_to_uri; +use crate::utils::{convert_slice_path_to_uri, span_to_range}; use crate::{notifications, show_popup}; use slicec::diagnostics::{Diagnostic, DiagnosticLevel, Note}; use std::collections::{HashMap, HashSet}; -use tower_lsp::lsp_types::{ - DiagnosticRelatedInformation, Location, NumberOrString, Position, Range, Url, -}; +use tower_lsp::lsp_types::{DiagnosticRelatedInformation, Location, NumberOrString, Url}; use tower_lsp::Client; /// Publishes diagnostics for all files in a given configuration set. @@ -116,17 +114,7 @@ pub fn try_into_lsp_diagnostic( // Map the spans to ranges, if span is none, return the slicec diagnostic let range = match diagnostic.span() { - Some(span) => { - let start = tower_lsp::lsp_types::Position::new( - (span.start.row - 1) as u32, - (span.start.col - 1) as u32, - ); - let end = tower_lsp::lsp_types::Position::new( - (span.end.row - 1) as u32, - (span.end.col - 1) as u32, - ); - Range::new(start, end) - } + Some(span) => span_to_range(span.clone()), None => return Err(diagnostic), }; @@ -156,19 +144,12 @@ pub fn try_into_lsp_diagnostic( fn try_into_lsp_diagnostic_related_information( note: &Note, ) -> Option { - let span = note.span.as_ref()?; - let file_path = convert_slice_path_to_uri(&span.file)?; - let start_position = Position::new((span.start.row - 1) as u32, (span.start.col - 1) as u32); - let end_position = Position::new((span.end.row - 1) as u32, (span.end.col - 1) as u32); + let span = note.span.clone()?; + let uri = convert_slice_path_to_uri(&span.file)?; + let range = span_to_range(span); Some(DiagnosticRelatedInformation { - location: Location { - uri: file_path, - range: Range { - start: start_position, - end: end_position, - }, - }, + location: Location { uri, range }, message: note.message.clone(), }) } diff --git a/server/src/hover.rs b/server/src/hover.rs index c087a20..f7bd095 100644 --- a/server/src/hover.rs +++ b/server/src/hover.rs @@ -1,33 +1,18 @@ // Copyright (c) ZeroC, Inc. +use crate::utils::position_to_location; use slicec::{ grammar::{Element, Enum, Primitive, Symbol, TypeRef, TypeRefDefinition, Types}, slice_file::{Location, SliceFile}, visitor::Visitor, }; -use tower_lsp::lsp_types::{Hover, HoverContents, MarkedString, Position}; +use tower_lsp::lsp_types::Position; -pub fn try_into_hover_result( - file: &SliceFile, - position: Position, -) -> tower_lsp::jsonrpc::Result { - // Convert position to row and column 1 based - let col = (position.character + 1) as usize; - let row = (position.line + 1) as usize; - - let mut visitor = HoverVisitor::new(Location { row, col }); +pub fn get_hover_message(file: &SliceFile, position: Position) -> Option { + let mut visitor = HoverVisitor::new(position_to_location(position)); file.visit_with(&mut visitor); - // If we found a message, return it as a hover result, otherwise return None. - visitor - .found_message - .map(|message| Hover { - contents: HoverContents::Scalar(MarkedString::String(message)), - range: None, - }) - .ok_or(tower_lsp::jsonrpc::Error::invalid_params( - "No hover information found", - )) + visitor.found_message } struct HoverVisitor { diff --git a/server/src/jump_definition.rs b/server/src/jump_definition.rs index 97b9922..fda0329 100644 --- a/server/src/jump_definition.rs +++ b/server/src/jump_definition.rs @@ -1,5 +1,6 @@ // Copyright (c) ZeroC, Inc. +use crate::utils::position_to_location; use slicec::{ grammar::{ Class, Commentable, CustomType, Entity, Enum, Enumerator, Exception, Field, Identifier, @@ -12,11 +13,7 @@ use slicec::{ use tower_lsp::lsp_types::Position; pub fn get_definition_span(file: &SliceFile, position: Position) -> Option { - // Convert position to row and column 1 based - let col = (position.character + 1) as usize; - let row = (position.line + 1) as usize; - - let mut visitor = JumpVisitor::new(Location { row, col }); + let mut visitor = JumpVisitor::new(position_to_location(position)); file.visit_with(&mut visitor); visitor.found_span diff --git a/server/src/main.rs b/server/src/main.rs index a33170e..b8320b2 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,7 +1,7 @@ // Copyright (c) ZeroC, Inc. use crate::diagnostic_ext::{clear_diagnostics, process_diagnostics, publish_diagnostics_for_set}; -use crate::hover::try_into_hover_result; +use crate::hover::get_hover_message; use crate::jump_definition::get_definition_span; use crate::notifications::{ShowNotification, ShowNotificationParams}; use crate::session::Session; @@ -10,7 +10,7 @@ use std::ops::DerefMut; use std::{collections::HashMap, path::Path}; use tokio::sync::Mutex; use tower_lsp::{jsonrpc::Error, lsp_types::*, Client, LanguageServer, LspService, Server}; -use utils::{convert_slice_path_to_uri, url_to_sanitized_file_path}; +use utils::{convert_slice_path_to_uri, span_to_range, url_to_sanitized_file_path}; mod configuration_set; mod diagnostic_ext; @@ -225,17 +225,9 @@ impl LanguageServer for Backend { .get(&file_path) .and_then(|file| get_definition_span(file, position)) .map(|location| { - let start = Position { - line: (location.start.row - 1) as u32, - character: (location.start.col - 1) as u32, - }; - let end = Position { - line: (location.end.row - 1) as u32, - character: (location.end.col - 1) as u32, - }; GotoDefinitionResponse::Scalar(Location { uri: uri.clone(), - range: Range::new(start, end), + range: span_to_range(location), }) }) })) @@ -256,7 +248,11 @@ impl LanguageServer for Backend { let files = &set.compilation_data.files; files .get(&file_path) - .and_then(|file| try_into_hover_result(file, position).ok()) + .and_then(|file| get_hover_message(file, position)) + .map(|message| Hover { + contents: HoverContents::Scalar(MarkedString::String(message)), + range: None, + }) })) } diff --git a/server/src/utils.rs b/server/src/utils.rs index bc3613d..8d7772e 100644 --- a/server/src/utils.rs +++ b/server/src/utils.rs @@ -1,7 +1,9 @@ // Copyright (c) ZeroC, Inc. use std::path::{Path, PathBuf}; -use tower_lsp::lsp_types::Url; + +use slicec::slice_file::{Location, Span}; +use tower_lsp::lsp_types::{Position, Range, Url}; // This helper function converts a Url from tower_lsp into a path that can be used to // retrieve a file from the compilation state from slicec. @@ -42,3 +44,23 @@ pub fn sanitize_path(s: &str) -> String { pub fn sanitize_path(s: &str) -> String { s.to_owned() } + +/// Converts a [`slicec::slice_file::Span`] into a [`tower_lsp::lsp_types::Range`]. +pub fn span_to_range(span: Span) -> Range { + let start = Position::new( + (span.start.row - 1) as u32, + (span.start.col - 1) as u32, + ); + let end = Position::new( + (span.end.row - 1) as u32, + (span.end.col - 1) as u32, + ); + Range::new(start, end) +} + +/// Converts a [`tower_lsp::lsp_types::Position`] into a [`slicec::slice_file::Location`]. +pub fn position_to_location(position: Position) -> Location { + let row = (position.line + 1) as usize; + let col = (position.character + 1) as usize; + Location { row, col } +}