From 8ae56fa6d0e8a03d6ad75919d6be953f5fc27083 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 13 Aug 2018 16:35:17 +0300 Subject: Stupid goto definition --- crates/server/src/caps.rs | 2 +- crates/server/src/conv.rs | 26 +++++++++++++++++++++++++- crates/server/src/main_loop/handlers.rs | 27 +++++++++++++++++++-------- crates/server/src/main_loop/mod.rs | 4 ++++ crates/server/src/req.rs | 1 + 5 files changed, 50 insertions(+), 10 deletions(-) (limited to 'crates/server/src') diff --git a/crates/server/src/caps.rs b/crates/server/src/caps.rs index 4fd28b7c8..ffebd9b47 100644 --- a/crates/server/src/caps.rs +++ b/crates/server/src/caps.rs @@ -20,7 +20,7 @@ pub fn server_capabilities() -> ServerCapabilities { hover_provider: None, completion_provider: None, signature_help_provider: None, - definition_provider: None, + definition_provider: Some(true), type_definition_provider: None, implementation_provider: None, references_provider: None, diff --git a/crates/server/src/conv.rs b/crates/server/src/conv.rs index 0ed989b32..1c31d32fe 100644 --- a/crates/server/src/conv.rs +++ b/crates/server/src/conv.rs @@ -1,7 +1,11 @@ -use languageserver_types::{Range, SymbolKind, Position, TextEdit}; +use std::path::Path; + +use languageserver_types::{Range, SymbolKind, Position, TextEdit, Location, Url}; use libeditor::{LineIndex, LineCol, Edit, AtomEdit}; use libsyntax2::{SyntaxKind, TextUnit, TextRange}; +use Result; + pub trait Conv { type Output; fn conv(self) -> Self::Output; @@ -13,6 +17,12 @@ pub trait ConvWith { fn conv_with(self, ctx: &Self::Ctx) -> Self::Output; } +pub trait TryConvWith { + type Ctx; + type Output; + fn try_conv_with(self, ctx: &Self::Ctx) -> Result; +} + impl Conv for SyntaxKind { type Output = SymbolKind; @@ -104,6 +114,20 @@ impl ConvWith for AtomEdit { } } +impl<'a> TryConvWith for (&'a Path, TextRange) { + type Ctx = LineIndex; + type Output = Location; + + fn try_conv_with(self, line_index: &LineIndex) -> Result { + let loc = Location::new( + Url::from_file_path(self.0) + .map_err(|()| format_err!("can't convert path to url: {}", self.0.display()))?, + self.1.conv_with(line_index), + ); + Ok(loc) + } +} + pub trait MapConvWith<'a>: Sized { type Ctx; diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs index f51909280..e9dc78420 100644 --- a/crates/server/src/main_loop/handlers.rs +++ b/crates/server/src/main_loop/handlers.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use languageserver_types::{ Diagnostic, DiagnosticSeverity, Url, DocumentSymbol, Command, TextDocumentIdentifier, WorkspaceEdit, - SymbolInformation, Location, + SymbolInformation, }; use libanalysis::{World, Query}; use libeditor; @@ -13,7 +13,7 @@ use serde_json::{to_value, from_value}; use ::{ req::{self, Decoration}, Result, util::FilePath, - conv::{Conv, ConvWith, MapConvWith}, + conv::{Conv, ConvWith, TryConvWith, MapConvWith}, }; pub fn handle_syntax_tree( @@ -115,15 +115,10 @@ pub fn handle_workspace_symbol( for (path, symbol) in world.world_symbols(query).take(128) { let line_index = world.file_line_index(path)?; - let info = SymbolInformation { name: symbol.name.to_string(), kind: symbol.kind.conv(), - location: Location::new( - Url::from_file_path(path) - .map_err(|()| format_err!("invalid url"))?, - symbol.node_range.conv_with(&line_index), - ), + location: (path, symbol.node_range).try_conv_with(&line_index)?, container_name: None, }; acc.push(info); @@ -132,6 +127,22 @@ pub fn handle_workspace_symbol( Ok(Some(acc)) } +pub fn handle_goto_definition( + world: World, + params: req::TextDocumentPositionParams, +) -> Result> { + let path = params.text_document.file_path()?; + let line_index = world.file_line_index(&path)?; + let offset = params.position.conv_with(&line_index); + let mut res = Vec::new(); + for (path, symbol) in world.approximately_resolve_symbol(&path, offset)? { + let line_index = world.file_line_index(path)?; + let location = (path, symbol.node_range).try_conv_with(&line_index)?; + res.push(location) + } + Ok(Some(req::GotoDefinitionResponse::Array(res))) +} + pub fn handle_execute_command( world: World, mut params: req::ExecuteCommandParams, diff --git a/crates/server/src/main_loop/mod.rs b/crates/server/src/main_loop/mod.rs index e8b24355c..bc898c17b 100644 --- a/crates/server/src/main_loop/mod.rs +++ b/crates/server/src/main_loop/mod.rs @@ -26,6 +26,7 @@ use { handle_code_action, handle_execute_command, handle_workspace_symbol, + handle_goto_definition, }, }; @@ -152,6 +153,9 @@ fn on_request( handle_request_on_threadpool::( &mut req, pool, world, sender, handle_workspace_symbol, )?; + handle_request_on_threadpool::( + &mut req, pool, world, sender, handle_goto_definition, + )?; dispatch::handle_request::(&mut req, |params, resp| { io.send(RawMsg::Response(resp.into_response(Ok(None))?)); diff --git a/crates/server/src/req.rs b/crates/server/src/req.rs index a8cc9b537..17ef10e43 100644 --- a/crates/server/src/req.rs +++ b/crates/server/src/req.rs @@ -9,6 +9,7 @@ pub use languageserver_types::{ CodeActionParams, ApplyWorkspaceEditParams, ExecuteCommandParams, WorkspaceSymbolParams, + TextDocumentPositionParams, }; -- cgit v1.2.3