aboutsummaryrefslogtreecommitdiff
path: root/crates/server
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-11 12:44:12 +0100
committerAleksey Kladov <[email protected]>2018-08-11 12:44:12 +0100
commitf2291d6a760f8a2d15074b5874facb03f5f838bc (patch)
tree00faff0402a675c4a041966e71b1789bfb086dcc /crates/server
parent7afd84febc76a75a3ed1be75c57ff35d7b8b3de6 (diff)
doc symbols
Diffstat (limited to 'crates/server')
-rw-r--r--crates/server/Cargo.toml8
-rw-r--r--crates/server/src/caps.rs2
-rw-r--r--crates/server/src/handlers.rs48
-rw-r--r--crates/server/src/main.rs10
-rw-r--r--crates/server/src/req.rs4
-rw-r--r--crates/server/src/util.rs5
6 files changed, 65 insertions, 12 deletions
diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml
index b5e4e1926..4c25b06e0 100644
--- a/crates/server/Cargo.toml
+++ b/crates/server/Cargo.toml
@@ -5,7 +5,6 @@ authors = ["Aleksey Kladov <[email protected]>"]
5 5
6[dependencies] 6[dependencies]
7failure = "0.1.2" 7failure = "0.1.2"
8languageserver-types = "0.48.0"
9serde_json = "1.0.24" 8serde_json = "1.0.24"
10serde = "1.0.71" 9serde = "1.0.71"
11serde_derive = "1.0.71" 10serde_derive = "1.0.71"
@@ -14,8 +13,13 @@ crossbeam-channel = "0.2.4"
14threadpool = "1.7.1" 13threadpool = "1.7.1"
15flexi_logger = "0.9.0" 14flexi_logger = "0.9.0"
16log = "0.4.3" 15log = "0.4.3"
17url = "1.1.0"
18url_serde = "0.2.0" 16url_serde = "0.2.0"
19 17
18libsyntax2 = { path = "../libsyntax2" }
20libeditor = { path = "../libeditor" } 19libeditor = { path = "../libeditor" }
21libanalysis = { path = "../libanalysis" } 20libanalysis = { path = "../libanalysis" }
21
22[dependencies.languageserver-types]
23git = "https://github.com/matklad/languageserver-types"
24rev = "70e6bf548b901f01dc249c20378d26dd4996c25f"
25
diff --git a/crates/server/src/caps.rs b/crates/server/src/caps.rs
index 3d89c64a9..dca07ebc9 100644
--- a/crates/server/src/caps.rs
+++ b/crates/server/src/caps.rs
@@ -23,7 +23,7 @@ pub const SERVER_CAPABILITIES: ServerCapabilities = ServerCapabilities {
23 implementation_provider: None, 23 implementation_provider: None,
24 references_provider: None, 24 references_provider: None,
25 document_highlight_provider: None, 25 document_highlight_provider: None,
26 document_symbol_provider: None, 26 document_symbol_provider: Some(true),
27 workspace_symbol_provider: None, 27 workspace_symbol_provider: None,
28 code_action_provider: None, 28 code_action_provider: None,
29 code_lens_provider: None, 29 code_lens_provider: None,
diff --git a/crates/server/src/handlers.rs b/crates/server/src/handlers.rs
index 8b7e00c92..51e940ef7 100644
--- a/crates/server/src/handlers.rs
+++ b/crates/server/src/handlers.rs
@@ -1,5 +1,5 @@
1use url::Url; 1use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity, Url, DocumentSymbol, SymbolKind};
2use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity}; 2use libsyntax2::SyntaxKind;
3use libanalysis::World; 3use libanalysis::World;
4use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit}; 4use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit};
5 5
@@ -34,6 +34,50 @@ pub fn handle_extend_selection(
34 Ok(req::ExtendSelectionResult { selections }) 34 Ok(req::ExtendSelectionResult { selections })
35} 35}
36 36
37pub fn handle_document_symbol(
38 world: World,
39 params: req::DocumentSymbolParams,
40) -> Result<Option<req::DocumentSymbolResponse>> {
41 let path = params.text_document.file_path()?;
42 let file = world.file_syntax(&path)?;
43 let line_index = world.file_line_index(&path)?;
44
45 let mut res: Vec<DocumentSymbol> = Vec::new();
46
47 for symbol in libeditor::file_symbols(&file) {
48 let doc_symbol = DocumentSymbol {
49 name: symbol.name.clone(),
50 detail: Some(symbol.name),
51 kind: to_symbol_kind(symbol.kind),
52 deprecated: None,
53 range: to_vs_range(&line_index, symbol.node_range),
54 selection_range: to_vs_range(&line_index, symbol.name_range),
55 children: None,
56 };
57 if let Some(idx) = symbol.parent {
58 let children = &mut res[idx].children;
59 if children.is_none() {
60 *children = Some(Vec::new());
61 }
62 children.as_mut().unwrap().push(doc_symbol);
63 } else {
64 res.push(doc_symbol);
65 }
66 }
67 Ok(Some(req::DocumentSymbolResponse::Nested(res)))
68}
69
70fn to_symbol_kind(kind: SyntaxKind) -> SymbolKind {
71 match kind {
72 SyntaxKind::FUNCTION => SymbolKind::Function,
73 SyntaxKind::STRUCT => SymbolKind::Struct,
74 SyntaxKind::ENUM => SymbolKind::Enum,
75 SyntaxKind::TRAIT => SymbolKind::Interface,
76 SyntaxKind::MODULE => SymbolKind::Module,
77 _ => SymbolKind::Variable,
78 }
79}
80
37pub fn publish_diagnostics(world: World, uri: Url) -> Result<req::PublishDiagnosticsParams> { 81pub fn publish_diagnostics(world: World, uri: Url) -> Result<req::PublishDiagnosticsParams> {
38 let path = uri.file_path()?; 82 let path = uri.file_path()?;
39 let file = world.file_syntax(&path)?; 83 let file = world.file_syntax(&path)?;
diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs
index aeb4f807b..916638d49 100644
--- a/crates/server/src/main.rs
+++ b/crates/server/src/main.rs
@@ -11,11 +11,11 @@ extern crate crossbeam_channel;
11extern crate threadpool; 11extern crate threadpool;
12#[macro_use] 12#[macro_use]
13extern crate log; 13extern crate log;
14extern crate url;
15extern crate url_serde; 14extern crate url_serde;
16extern crate flexi_logger; 15extern crate flexi_logger;
17extern crate libeditor; 16extern crate libeditor;
18extern crate libanalysis; 17extern crate libanalysis;
18extern crate libsyntax2;
19 19
20mod io; 20mod io;
21mod caps; 21mod caps;
@@ -27,12 +27,13 @@ mod util;
27use threadpool::ThreadPool; 27use threadpool::ThreadPool;
28use crossbeam_channel::{bounded, Sender, Receiver}; 28use crossbeam_channel::{bounded, Sender, Receiver};
29use flexi_logger::Logger; 29use flexi_logger::Logger;
30use url::Url; 30use languageserver_types::Url;
31use libanalysis::{WorldState, World}; 31use libanalysis::{WorldState, World};
32 32
33use ::{ 33use ::{
34 io::{Io, RawMsg, RawRequest}, 34 io::{Io, RawMsg, RawRequest},
35 handlers::{handle_syntax_tree, handle_extend_selection, publish_diagnostics, publish_decorations}, 35 handlers::{handle_syntax_tree, handle_extend_selection, publish_diagnostics, publish_decorations,
36 handle_document_symbol},
36 util::{FilePath, FnBox} 37 util::{FilePath, FnBox}
37}; 38};
38 39
@@ -178,6 +179,9 @@ fn main_loop(
178 handle_request_on_threadpool::<req::ExtendSelection>( 179 handle_request_on_threadpool::<req::ExtendSelection>(
179 &mut req, pool, world, &sender, handle_extend_selection 180 &mut req, pool, world, &sender, handle_extend_selection
180 )?; 181 )?;
182 handle_request_on_threadpool::<req::DocumentSymbolRequest>(
183 &mut req, pool, world, &sender, handle_document_symbol
184 )?;
181 let mut shutdown = false; 185 let mut shutdown = false;
182 dispatch::handle_request::<req::Shutdown, _>(&mut req, |(), resp| { 186 dispatch::handle_request::<req::Shutdown, _>(&mut req, |(), resp| {
183 resp.result(io, ())?; 187 resp.result(io, ())?;
diff --git a/crates/server/src/req.rs b/crates/server/src/req.rs
index 480fbabcd..6a0926084 100644
--- a/crates/server/src/req.rs
+++ b/crates/server/src/req.rs
@@ -1,11 +1,11 @@
1use serde::{ser::Serialize, de::DeserializeOwned}; 1use serde::{ser::Serialize, de::DeserializeOwned};
2use url::Url; 2use languageserver_types::{TextDocumentIdentifier, Range, Url};
3use languageserver_types::{TextDocumentIdentifier, Range};
4use url_serde; 3use url_serde;
5 4
6pub use languageserver_types::{ 5pub use languageserver_types::{
7 request::*, notification::*, 6 request::*, notification::*,
8 InitializeResult, PublishDiagnosticsParams, 7 InitializeResult, PublishDiagnosticsParams,
8 DocumentSymbolParams, DocumentSymbolResponse
9}; 9};
10 10
11 11
diff --git a/crates/server/src/util.rs b/crates/server/src/util.rs
index 3691852f0..e4c226f93 100644
--- a/crates/server/src/util.rs
+++ b/crates/server/src/util.rs
@@ -1,5 +1,6 @@
1use std::path::PathBuf; 1use std::path::PathBuf;
2use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentIdentifier}; 2use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier,
3 TextDocumentIdentifier, Url};
3use ::{Result}; 4use ::{Result};
4 5
5pub trait FnBox<A, R>: Send { 6pub trait FnBox<A, R>: Send {
@@ -34,7 +35,7 @@ impl FilePath for TextDocumentIdentifier {
34 } 35 }
35} 36}
36 37
37impl FilePath for ::url::Url { 38impl FilePath for Url {
38 fn file_path(&self) -> Result<PathBuf> { 39 fn file_path(&self) -> Result<PathBuf> {
39 self.to_file_path() 40 self.to_file_path()
40 .map_err(|()| format_err!("invalid uri: {}", self)) 41 .map_err(|()| format_err!("invalid uri: {}", self))