Skip to content

Commit

Permalink
Add helper methods for converting between 'slicec' and 'lsp_tower' ty…
Browse files Browse the repository at this point in the history
…pes. (#59)
  • Loading branch information
InsertCreativityHere authored Jul 23, 2024
1 parent 7c1fecd commit dc52db3
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 64 deletions.
33 changes: 7 additions & 26 deletions server/src/diagnostic_ext.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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),
};

Expand Down Expand Up @@ -156,19 +144,12 @@ pub fn try_into_lsp_diagnostic(
fn try_into_lsp_diagnostic_related_information(
note: &Note,
) -> Option<tower_lsp::lsp_types::DiagnosticRelatedInformation> {
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(),
})
}
25 changes: 5 additions & 20 deletions server/src/hover.rs
Original file line number Diff line number Diff line change
@@ -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<Hover> {
// 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<String> {
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 {
Expand Down
7 changes: 2 additions & 5 deletions server/src/jump_definition.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -12,11 +13,7 @@ use slicec::{
use tower_lsp::lsp_types::Position;

pub fn get_definition_span(file: &SliceFile, position: Position) -> Option<Span> {
// 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
Expand Down
20 changes: 8 additions & 12 deletions server/src/main.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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),
})
})
}))
Expand All @@ -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,
})
}))
}

Expand Down
24 changes: 23 additions & 1 deletion server/src/utils.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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 }
}

0 comments on commit dc52db3

Please sign in to comment.