aboutsummaryrefslogtreecommitdiff
path: root/crates/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/server/src')
-rw-r--r--crates/server/src/caps.rs2
-rw-r--r--crates/server/src/conv.rs26
-rw-r--r--crates/server/src/main_loop/handlers.rs27
-rw-r--r--crates/server/src/main_loop/mod.rs4
-rw-r--r--crates/server/src/req.rs1
5 files changed, 50 insertions, 10 deletions
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 {
20 hover_provider: None, 20 hover_provider: None,
21 completion_provider: None, 21 completion_provider: None,
22 signature_help_provider: None, 22 signature_help_provider: None,
23 definition_provider: None, 23 definition_provider: Some(true),
24 type_definition_provider: None, 24 type_definition_provider: None,
25 implementation_provider: None, 25 implementation_provider: None,
26 references_provider: None, 26 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 @@
1use languageserver_types::{Range, SymbolKind, Position, TextEdit}; 1use std::path::Path;
2
3use languageserver_types::{Range, SymbolKind, Position, TextEdit, Location, Url};
2use libeditor::{LineIndex, LineCol, Edit, AtomEdit}; 4use libeditor::{LineIndex, LineCol, Edit, AtomEdit};
3use libsyntax2::{SyntaxKind, TextUnit, TextRange}; 5use libsyntax2::{SyntaxKind, TextUnit, TextRange};
4 6
7use Result;
8
5pub trait Conv { 9pub trait Conv {
6 type Output; 10 type Output;
7 fn conv(self) -> Self::Output; 11 fn conv(self) -> Self::Output;
@@ -13,6 +17,12 @@ pub trait ConvWith {
13 fn conv_with(self, ctx: &Self::Ctx) -> Self::Output; 17 fn conv_with(self, ctx: &Self::Ctx) -> Self::Output;
14} 18}
15 19
20pub trait TryConvWith {
21 type Ctx;
22 type Output;
23 fn try_conv_with(self, ctx: &Self::Ctx) -> Result<Self::Output>;
24}
25
16impl Conv for SyntaxKind { 26impl Conv for SyntaxKind {
17 type Output = SymbolKind; 27 type Output = SymbolKind;
18 28
@@ -104,6 +114,20 @@ impl ConvWith for AtomEdit {
104 } 114 }
105} 115}
106 116
117impl<'a> TryConvWith for (&'a Path, TextRange) {
118 type Ctx = LineIndex;
119 type Output = Location;
120
121 fn try_conv_with(self, line_index: &LineIndex) -> Result<Location> {
122 let loc = Location::new(
123 Url::from_file_path(self.0)
124 .map_err(|()| format_err!("can't convert path to url: {}", self.0.display()))?,
125 self.1.conv_with(line_index),
126 );
127 Ok(loc)
128 }
129}
130
107 131
108pub trait MapConvWith<'a>: Sized { 132pub trait MapConvWith<'a>: Sized {
109 type Ctx; 133 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;
3use languageserver_types::{ 3use languageserver_types::{
4 Diagnostic, DiagnosticSeverity, Url, DocumentSymbol, 4 Diagnostic, DiagnosticSeverity, Url, DocumentSymbol,
5 Command, TextDocumentIdentifier, WorkspaceEdit, 5 Command, TextDocumentIdentifier, WorkspaceEdit,
6 SymbolInformation, Location, 6 SymbolInformation,
7}; 7};
8use libanalysis::{World, Query}; 8use libanalysis::{World, Query};
9use libeditor; 9use libeditor;
@@ -13,7 +13,7 @@ use serde_json::{to_value, from_value};
13use ::{ 13use ::{
14 req::{self, Decoration}, Result, 14 req::{self, Decoration}, Result,
15 util::FilePath, 15 util::FilePath,
16 conv::{Conv, ConvWith, MapConvWith}, 16 conv::{Conv, ConvWith, TryConvWith, MapConvWith},
17}; 17};
18 18
19pub fn handle_syntax_tree( 19pub fn handle_syntax_tree(
@@ -115,15 +115,10 @@ pub fn handle_workspace_symbol(
115 115
116 for (path, symbol) in world.world_symbols(query).take(128) { 116 for (path, symbol) in world.world_symbols(query).take(128) {
117 let line_index = world.file_line_index(path)?; 117 let line_index = world.file_line_index(path)?;
118
119 let info = SymbolInformation { 118 let info = SymbolInformation {
120 name: symbol.name.to_string(), 119 name: symbol.name.to_string(),
121 kind: symbol.kind.conv(), 120 kind: symbol.kind.conv(),
122 location: Location::new( 121 location: (path, symbol.node_range).try_conv_with(&line_index)?,
123 Url::from_file_path(path)
124 .map_err(|()| format_err!("invalid url"))?,
125 symbol.node_range.conv_with(&line_index),
126 ),
127 container_name: None, 122 container_name: None,
128 }; 123 };
129 acc.push(info); 124 acc.push(info);
@@ -132,6 +127,22 @@ pub fn handle_workspace_symbol(
132 Ok(Some(acc)) 127 Ok(Some(acc))
133} 128}
134 129
130pub fn handle_goto_definition(
131 world: World,
132 params: req::TextDocumentPositionParams,
133) -> Result<Option<req::GotoDefinitionResponse>> {
134 let path = params.text_document.file_path()?;
135 let line_index = world.file_line_index(&path)?;
136 let offset = params.position.conv_with(&line_index);
137 let mut res = Vec::new();
138 for (path, symbol) in world.approximately_resolve_symbol(&path, offset)? {
139 let line_index = world.file_line_index(path)?;
140 let location = (path, symbol.node_range).try_conv_with(&line_index)?;
141 res.push(location)
142 }
143 Ok(Some(req::GotoDefinitionResponse::Array(res)))
144}
145
135pub fn handle_execute_command( 146pub fn handle_execute_command(
136 world: World, 147 world: World,
137 mut params: req::ExecuteCommandParams, 148 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 {
26 handle_code_action, 26 handle_code_action,
27 handle_execute_command, 27 handle_execute_command,
28 handle_workspace_symbol, 28 handle_workspace_symbol,
29 handle_goto_definition,
29 }, 30 },
30}; 31};
31 32
@@ -152,6 +153,9 @@ fn on_request(
152 handle_request_on_threadpool::<req::WorkspaceSymbol>( 153 handle_request_on_threadpool::<req::WorkspaceSymbol>(
153 &mut req, pool, world, sender, handle_workspace_symbol, 154 &mut req, pool, world, sender, handle_workspace_symbol,
154 )?; 155 )?;
156 handle_request_on_threadpool::<req::GotoDefinition>(
157 &mut req, pool, world, sender, handle_goto_definition,
158 )?;
155 dispatch::handle_request::<req::ExecuteCommand, _>(&mut req, |params, resp| { 159 dispatch::handle_request::<req::ExecuteCommand, _>(&mut req, |params, resp| {
156 io.send(RawMsg::Response(resp.into_response(Ok(None))?)); 160 io.send(RawMsg::Response(resp.into_response(Ok(None))?));
157 161
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::{
9 CodeActionParams, ApplyWorkspaceEditParams, 9 CodeActionParams, ApplyWorkspaceEditParams,
10 ExecuteCommandParams, 10 ExecuteCommandParams,
11 WorkspaceSymbolParams, 11 WorkspaceSymbolParams,
12 TextDocumentPositionParams,
12}; 13};
13 14
14 15