diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/cli/src/main.rs | 4 | ||||
-rw-r--r-- | crates/libeditor/src/lib.rs | 39 | ||||
-rw-r--r-- | crates/server/Cargo.toml | 8 | ||||
-rw-r--r-- | crates/server/src/caps.rs | 2 | ||||
-rw-r--r-- | crates/server/src/handlers.rs | 48 | ||||
-rw-r--r-- | crates/server/src/main.rs | 10 | ||||
-rw-r--r-- | crates/server/src/req.rs | 4 | ||||
-rw-r--r-- | crates/server/src/util.rs | 5 |
8 files changed, 68 insertions, 52 deletions
diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 863aeb99d..b6e9139c7 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs | |||
@@ -10,7 +10,7 @@ use std::{ | |||
10 | }; | 10 | }; |
11 | use clap::{App, Arg, SubCommand}; | 11 | use clap::{App, Arg, SubCommand}; |
12 | use tools::collect_tests; | 12 | use tools::collect_tests; |
13 | use libeditor::{File, syntax_tree, symbols}; | 13 | use libeditor::{File, syntax_tree, file_symbols}; |
14 | 14 | ||
15 | type Result<T> = ::std::result::Result<T, failure::Error>; | 15 | type Result<T> = ::std::result::Result<T, failure::Error>; |
16 | 16 | ||
@@ -51,7 +51,7 @@ fn main() -> Result<()> { | |||
51 | } | 51 | } |
52 | ("symbols", _) => { | 52 | ("symbols", _) => { |
53 | let file = file()?; | 53 | let file = file()?; |
54 | for s in symbols(&file) { | 54 | for s in file_symbols(&file) { |
55 | println!("{:?}", s); | 55 | println!("{:?}", s); |
56 | } | 56 | } |
57 | } | 57 | } |
diff --git a/crates/libeditor/src/lib.rs b/crates/libeditor/src/lib.rs index 4ea344b17..013d27450 100644 --- a/crates/libeditor/src/lib.rs +++ b/crates/libeditor/src/lib.rs | |||
@@ -7,7 +7,7 @@ mod line_index; | |||
7 | 7 | ||
8 | use libsyntax2::{ | 8 | use libsyntax2::{ |
9 | ast::{self, NameOwner}, | 9 | ast::{self, NameOwner}, |
10 | SyntaxNodeRef, AstNode, | 10 | AstNode, |
11 | algo::walk, | 11 | algo::walk, |
12 | SyntaxKind::*, | 12 | SyntaxKind::*, |
13 | }; | 13 | }; |
@@ -100,19 +100,6 @@ pub fn syntax_tree(file: &ast::File) -> String { | |||
100 | ::libsyntax2::utils::dump_tree(&file.syntax()) | 100 | ::libsyntax2::utils::dump_tree(&file.syntax()) |
101 | } | 101 | } |
102 | 102 | ||
103 | pub fn symbols(file: &ast::File) -> Vec<Symbol> { | ||
104 | let syntax = file.syntax(); | ||
105 | let res: Vec<Symbol> = walk::preorder(syntax.as_ref()) | ||
106 | .filter_map(Declaration::cast) | ||
107 | .filter_map(|decl| { | ||
108 | let name = decl.name()?; | ||
109 | let range = decl.range(); | ||
110 | Some(Symbol { name, range }) | ||
111 | }) | ||
112 | .collect(); | ||
113 | res // NLL :-( | ||
114 | } | ||
115 | |||
116 | pub fn runnables(file: &ast::File) -> Vec<Runnable> { | 103 | pub fn runnables(file: &ast::File) -> Vec<Runnable> { |
117 | file | 104 | file |
118 | .functions() | 105 | .functions() |
@@ -134,27 +121,3 @@ pub fn runnables(file: &ast::File) -> Vec<Runnable> { | |||
134 | }) | 121 | }) |
135 | .collect() | 122 | .collect() |
136 | } | 123 | } |
137 | |||
138 | |||
139 | struct Declaration<'f> (SyntaxNodeRef<'f>); | ||
140 | |||
141 | impl<'f> Declaration<'f> { | ||
142 | fn cast(node: SyntaxNodeRef<'f>) -> Option<Declaration<'f>> { | ||
143 | match node.kind() { | ||
144 | | STRUCT | ENUM | FUNCTION | TRAIT | ||
145 | | CONST_ITEM | STATIC_ITEM | MODULE | NAMED_FIELD | ||
146 | | TYPE_ITEM => Some(Declaration(node)), | ||
147 | _ => None | ||
148 | } | ||
149 | } | ||
150 | |||
151 | fn name(&self) -> Option<String> { | ||
152 | let name = self.0.children() | ||
153 | .find(|child| child.kind() == NAME)?; | ||
154 | Some(name.text()) | ||
155 | } | ||
156 | |||
157 | fn range(&self) -> TextRange { | ||
158 | self.0.range() | ||
159 | } | ||
160 | } | ||
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] |
7 | failure = "0.1.2" | 7 | failure = "0.1.2" |
8 | languageserver-types = "0.48.0" | ||
9 | serde_json = "1.0.24" | 8 | serde_json = "1.0.24" |
10 | serde = "1.0.71" | 9 | serde = "1.0.71" |
11 | serde_derive = "1.0.71" | 10 | serde_derive = "1.0.71" |
@@ -14,8 +13,13 @@ crossbeam-channel = "0.2.4" | |||
14 | threadpool = "1.7.1" | 13 | threadpool = "1.7.1" |
15 | flexi_logger = "0.9.0" | 14 | flexi_logger = "0.9.0" |
16 | log = "0.4.3" | 15 | log = "0.4.3" |
17 | url = "1.1.0" | ||
18 | url_serde = "0.2.0" | 16 | url_serde = "0.2.0" |
19 | 17 | ||
18 | libsyntax2 = { path = "../libsyntax2" } | ||
20 | libeditor = { path = "../libeditor" } | 19 | libeditor = { path = "../libeditor" } |
21 | libanalysis = { path = "../libanalysis" } | 20 | libanalysis = { path = "../libanalysis" } |
21 | |||
22 | [dependencies.languageserver-types] | ||
23 | git = "https://github.com/matklad/languageserver-types" | ||
24 | rev = "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 @@ | |||
1 | use url::Url; | 1 | use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity, Url, DocumentSymbol, SymbolKind}; |
2 | use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity}; | 2 | use libsyntax2::SyntaxKind; |
3 | use libanalysis::World; | 3 | use libanalysis::World; |
4 | use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit}; | 4 | use 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 | ||
37 | pub 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 | |||
70 | fn 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 | |||
37 | pub fn publish_diagnostics(world: World, uri: Url) -> Result<req::PublishDiagnosticsParams> { | 81 | pub 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; | |||
11 | extern crate threadpool; | 11 | extern crate threadpool; |
12 | #[macro_use] | 12 | #[macro_use] |
13 | extern crate log; | 13 | extern crate log; |
14 | extern crate url; | ||
15 | extern crate url_serde; | 14 | extern crate url_serde; |
16 | extern crate flexi_logger; | 15 | extern crate flexi_logger; |
17 | extern crate libeditor; | 16 | extern crate libeditor; |
18 | extern crate libanalysis; | 17 | extern crate libanalysis; |
18 | extern crate libsyntax2; | ||
19 | 19 | ||
20 | mod io; | 20 | mod io; |
21 | mod caps; | 21 | mod caps; |
@@ -27,12 +27,13 @@ mod util; | |||
27 | use threadpool::ThreadPool; | 27 | use threadpool::ThreadPool; |
28 | use crossbeam_channel::{bounded, Sender, Receiver}; | 28 | use crossbeam_channel::{bounded, Sender, Receiver}; |
29 | use flexi_logger::Logger; | 29 | use flexi_logger::Logger; |
30 | use url::Url; | 30 | use languageserver_types::Url; |
31 | use libanalysis::{WorldState, World}; | 31 | use libanalysis::{WorldState, World}; |
32 | 32 | ||
33 | use ::{ | 33 | use ::{ |
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 @@ | |||
1 | use serde::{ser::Serialize, de::DeserializeOwned}; | 1 | use serde::{ser::Serialize, de::DeserializeOwned}; |
2 | use url::Url; | 2 | use languageserver_types::{TextDocumentIdentifier, Range, Url}; |
3 | use languageserver_types::{TextDocumentIdentifier, Range}; | ||
4 | use url_serde; | 3 | use url_serde; |
5 | 4 | ||
6 | pub use languageserver_types::{ | 5 | pub 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 @@ | |||
1 | use std::path::PathBuf; | 1 | use std::path::PathBuf; |
2 | use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentIdentifier}; | 2 | use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, |
3 | TextDocumentIdentifier, Url}; | ||
3 | use ::{Result}; | 4 | use ::{Result}; |
4 | 5 | ||
5 | pub trait FnBox<A, R>: Send { | 6 | pub trait FnBox<A, R>: Send { |
@@ -34,7 +35,7 @@ impl FilePath for TextDocumentIdentifier { | |||
34 | } | 35 | } |
35 | } | 36 | } |
36 | 37 | ||
37 | impl FilePath for ::url::Url { | 38 | impl 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)) |