aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/libeditor/src/scope.rs14
-rw-r--r--crates/libeditor/tests/test.rs8
-rw-r--r--crates/libsyntax2/src/ast/generated.rs8
-rw-r--r--crates/libsyntax2/src/grammar.ron6
-rw-r--r--crates/server/src/main_loop/handlers.rs50
-rw-r--r--crates/server/src/main_loop/mod.rs4
-rw-r--r--crates/server/src/req.rs27
7 files changed, 115 insertions, 2 deletions
diff --git a/crates/libeditor/src/scope.rs b/crates/libeditor/src/scope.rs
index 76104b2cf..3d398a74c 100644
--- a/crates/libeditor/src/scope.rs
+++ b/crates/libeditor/src/scope.rs
@@ -61,7 +61,19 @@ fn compute_expr_scopes(expr: ast::Expr, scopes: &mut FnScopes, scope: ScopeId) {
61 compute_block_scopes(block, scopes, scope); 61 compute_block_scopes(block, scopes, scope);
62 } 62 }
63 } 63 }
64 // ForExpr(e) => TODO, 64 ast::Expr::ForExpr(e) => {
65 if let Some(expr) = e.iterable() {
66 compute_expr_scopes(expr, scopes, scope);
67 }
68 let mut scope = scope;
69 if let Some(pat) = e.pat() {
70 scope = scopes.new_scope(scope);
71 scopes.add_bindings(scope, pat);
72 }
73 if let Some(block) = e.body() {
74 compute_block_scopes(block, scopes, scope);
75 }
76 },
65 _ => { 77 _ => {
66 expr.syntax().children() 78 expr.syntax().children()
67 .filter_map(ast::Expr::cast) 79 .filter_map(ast::Expr::cast)
diff --git a/crates/libeditor/tests/test.rs b/crates/libeditor/tests/test.rs
index d051980b0..d8c24610d 100644
--- a/crates/libeditor/tests/test.rs
+++ b/crates/libeditor/tests/test.rs
@@ -286,6 +286,14 @@ fn quux() {
286} 286}
287", r#"[CompletionItem { name: "b" }, 287", r#"[CompletionItem { name: "b" },
288 CompletionItem { name: "a" }]"#); 288 CompletionItem { name: "a" }]"#);
289
290 do_check(r"
291fn quux() {
292 for x in &[1, 2, 3] {
293 <|>
294 }
295}
296", r#"[CompletionItem { name: "x" }]"#);
289} 297}
290 298
291fn file(text: &str) -> File { 299fn file(text: &str) -> File {
diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs
index 6891e857c..f99d1274a 100644
--- a/crates/libsyntax2/src/ast/generated.rs
+++ b/crates/libsyntax2/src/ast/generated.rs
@@ -539,6 +539,14 @@ impl<'a> AstNode<'a> for ForExpr<'a> {
539} 539}
540 540
541impl<'a> ForExpr<'a> { 541impl<'a> ForExpr<'a> {
542 pub fn pat(self) -> Option<Pat<'a>> {
543 super::child_opt(self)
544 }
545
546 pub fn iterable(self) -> Option<Expr<'a>> {
547 super::child_opt(self)
548 }
549
542 pub fn body(self) -> Option<Block<'a>> { 550 pub fn body(self) -> Option<Block<'a>> {
543 super::child_opt(self) 551 super::child_opt(self)
544 } 552 }
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron
index c9e128462..a98e9e2fd 100644
--- a/crates/libsyntax2/src/grammar.ron
+++ b/crates/libsyntax2/src/grammar.ron
@@ -344,7 +344,11 @@ Grammar(
344 options: [ ["body", "Block"] ] 344 options: [ ["body", "Block"] ]
345 ), 345 ),
346 "ForExpr": ( 346 "ForExpr": (
347 options: [ ["body", "Block"] ] 347 options: [
348 ["pat", "Pat"],
349 ["iterable", "Expr"],
350 ["body", "Block"] ,
351 ]
348 ), 352 ),
349 "WhileExpr": ( 353 "WhileExpr": (
350 options: [ 354 options: [
diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs
index 350eda7df..583af0900 100644
--- a/crates/server/src/main_loop/handlers.rs
+++ b/crates/server/src/main_loop/handlers.rs
@@ -204,6 +204,56 @@ pub fn handle_code_action(
204 return Ok(Some(res)); 204 return Ok(Some(res));
205} 205}
206 206
207pub fn handle_runnables(
208 world: ServerWorld,
209 params: req::RunnablesParams,
210) -> Result<Vec<req::Runnable>> {
211 let file_id = params.text_document.try_conv_with(&world)?;
212 let file = world.analysis().file_syntax(file_id)?;
213 let line_index = world.analysis().file_line_index(file_id)?;
214 let offset = params.position.map(|it| it.conv_with(&line_index));
215 let mut res = Vec::new();
216 for runnable in libeditor::runnables(&file) {
217 if let Some(offset) = offset {
218 if !contains_offset_nonstrict(runnable.range, offset) {
219 continue;
220 }
221 }
222
223 let r = req::Runnable {
224 range: runnable.range.conv_with(&line_index),
225 label: match &runnable.kind {
226 libeditor::RunnableKind::Test { name } =>
227 format!("test {}", name),
228 libeditor::RunnableKind::Bin =>
229 "run binary".to_string(),
230 },
231 bin: "cargo".to_string(),
232 args: match runnable.kind {
233 libeditor::RunnableKind::Test { name } => {
234 vec![
235 "test".to_string(),
236 "--".to_string(),
237 name,
238 "--nocapture".to_string(),
239 ]
240 }
241 libeditor::RunnableKind::Bin => vec!["run".to_string()]
242 },
243 env: {
244 let mut m = HashMap::new();
245 m.insert(
246 "RUST_BACKTRACE".to_string(),
247 "short".to_string(),
248 );
249 m
250 }
251 };
252 res.push(r);
253 }
254 return Ok(res);
255}
256
207pub fn handle_workspace_symbol( 257pub fn handle_workspace_symbol(
208 world: ServerWorld, 258 world: ServerWorld,
209 params: req::WorkspaceSymbolParams, 259 params: req::WorkspaceSymbolParams,
diff --git a/crates/server/src/main_loop/mod.rs b/crates/server/src/main_loop/mod.rs
index 5213ecc04..6d6ca6ae9 100644
--- a/crates/server/src/main_loop/mod.rs
+++ b/crates/server/src/main_loop/mod.rs
@@ -29,6 +29,7 @@ use {
29 handle_parent_module, 29 handle_parent_module,
30 handle_join_lines, 30 handle_join_lines,
31 handle_completion, 31 handle_completion,
32 handle_runnables,
32 }, 33 },
33}; 34};
34 35
@@ -138,6 +139,9 @@ fn on_request(
138 handle_request_on_threadpool::<req::CodeActionRequest>( 139 handle_request_on_threadpool::<req::CodeActionRequest>(
139 &mut req, pool, world, sender, handle_code_action, 140 &mut req, pool, world, sender, handle_code_action,
140 )?; 141 )?;
142 handle_request_on_threadpool::<req::Runnables>(
143 &mut req, pool, world, sender, handle_runnables,
144 )?;
141 handle_request_on_threadpool::<req::WorkspaceSymbol>( 145 handle_request_on_threadpool::<req::WorkspaceSymbol>(
142 &mut req, pool, world, sender, handle_workspace_symbol, 146 &mut req, pool, world, sender, handle_workspace_symbol,
143 )?; 147 )?;
diff --git a/crates/server/src/req.rs b/crates/server/src/req.rs
index 6d3466b66..e4138abba 100644
--- a/crates/server/src/req.rs
+++ b/crates/server/src/req.rs
@@ -1,3 +1,5 @@
1use std::collections::HashMap;
2
1use serde::{ser::Serialize, de::DeserializeOwned}; 3use serde::{ser::Serialize, de::DeserializeOwned};
2use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location}; 4use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location};
3use url_serde; 5use url_serde;
@@ -134,3 +136,28 @@ pub struct JoinLinesParams {
134 pub text_document: TextDocumentIdentifier, 136 pub text_document: TextDocumentIdentifier,
135 pub range: Range, 137 pub range: Range,
136} 138}
139
140pub enum Runnables {}
141
142impl Request for Runnables {
143 type Params = RunnablesParams;
144 type Result = Vec<Runnable>;
145 const METHOD: &'static str = "m/joinLines";
146}
147
148#[derive(Deserialize, Debug)]
149#[serde(rename_all = "camelCase")]
150pub struct RunnablesParams {
151 pub text_document: TextDocumentIdentifier,
152 pub position: Option<Position>,
153}
154
155#[derive(Serialize, Debug)]
156#[serde(rename_all = "camelCase")]
157pub struct Runnable {
158 pub range: Range,
159 pub label: String,
160 pub bin: String,
161 pub args: Vec<String>,
162 pub env: HashMap<String, String>,
163}