aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/cli/src/main.rs4
-rw-r--r--crates/libeditor/src/lib.rs39
-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
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};
11use clap::{App, Arg, SubCommand}; 11use clap::{App, Arg, SubCommand};
12use tools::collect_tests; 12use tools::collect_tests;
13use libeditor::{File, syntax_tree, symbols}; 13use libeditor::{File, syntax_tree, file_symbols};
14 14
15type Result<T> = ::std::result::Result<T, failure::Error>; 15type 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
8use libsyntax2::{ 8use 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
103pub 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
116pub fn runnables(file: &ast::File) -> Vec<Runnable> { 103pub 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
139struct Declaration<'f> (SyntaxNodeRef<'f>);
140
141impl<'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]
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))