Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Functions for Converting Between 'slicec' and 'tower_lsp' Types #59

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 }
}