mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 21:28:51 +00:00
Add runnables
This commit is contained in:
parent
b79c8b6d8a
commit
5751815314
7 changed files with 115 additions and 2 deletions
|
@ -61,7 +61,19 @@ fn compute_expr_scopes(expr: ast::Expr, scopes: &mut FnScopes, scope: ScopeId) {
|
|||
compute_block_scopes(block, scopes, scope);
|
||||
}
|
||||
}
|
||||
// ForExpr(e) => TODO,
|
||||
ast::Expr::ForExpr(e) => {
|
||||
if let Some(expr) = e.iterable() {
|
||||
compute_expr_scopes(expr, scopes, scope);
|
||||
}
|
||||
let mut scope = scope;
|
||||
if let Some(pat) = e.pat() {
|
||||
scope = scopes.new_scope(scope);
|
||||
scopes.add_bindings(scope, pat);
|
||||
}
|
||||
if let Some(block) = e.body() {
|
||||
compute_block_scopes(block, scopes, scope);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
expr.syntax().children()
|
||||
.filter_map(ast::Expr::cast)
|
||||
|
|
|
@ -286,6 +286,14 @@ fn quux() {
|
|||
}
|
||||
", r#"[CompletionItem { name: "b" },
|
||||
CompletionItem { name: "a" }]"#);
|
||||
|
||||
do_check(r"
|
||||
fn quux() {
|
||||
for x in &[1, 2, 3] {
|
||||
<|>
|
||||
}
|
||||
}
|
||||
", r#"[CompletionItem { name: "x" }]"#);
|
||||
}
|
||||
|
||||
fn file(text: &str) -> File {
|
||||
|
|
|
@ -539,6 +539,14 @@ impl<'a> AstNode<'a> for ForExpr<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ForExpr<'a> {
|
||||
pub fn pat(self) -> Option<Pat<'a>> {
|
||||
super::child_opt(self)
|
||||
}
|
||||
|
||||
pub fn iterable(self) -> Option<Expr<'a>> {
|
||||
super::child_opt(self)
|
||||
}
|
||||
|
||||
pub fn body(self) -> Option<Block<'a>> {
|
||||
super::child_opt(self)
|
||||
}
|
||||
|
|
|
@ -344,7 +344,11 @@ Grammar(
|
|||
options: [ ["body", "Block"] ]
|
||||
),
|
||||
"ForExpr": (
|
||||
options: [ ["body", "Block"] ]
|
||||
options: [
|
||||
["pat", "Pat"],
|
||||
["iterable", "Expr"],
|
||||
["body", "Block"] ,
|
||||
]
|
||||
),
|
||||
"WhileExpr": (
|
||||
options: [
|
||||
|
|
|
@ -204,6 +204,56 @@ pub fn handle_code_action(
|
|||
return Ok(Some(res));
|
||||
}
|
||||
|
||||
pub fn handle_runnables(
|
||||
world: ServerWorld,
|
||||
params: req::RunnablesParams,
|
||||
) -> Result<Vec<req::Runnable>> {
|
||||
let file_id = params.text_document.try_conv_with(&world)?;
|
||||
let file = world.analysis().file_syntax(file_id)?;
|
||||
let line_index = world.analysis().file_line_index(file_id)?;
|
||||
let offset = params.position.map(|it| it.conv_with(&line_index));
|
||||
let mut res = Vec::new();
|
||||
for runnable in libeditor::runnables(&file) {
|
||||
if let Some(offset) = offset {
|
||||
if !contains_offset_nonstrict(runnable.range, offset) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let r = req::Runnable {
|
||||
range: runnable.range.conv_with(&line_index),
|
||||
label: match &runnable.kind {
|
||||
libeditor::RunnableKind::Test { name } =>
|
||||
format!("test {}", name),
|
||||
libeditor::RunnableKind::Bin =>
|
||||
"run binary".to_string(),
|
||||
},
|
||||
bin: "cargo".to_string(),
|
||||
args: match runnable.kind {
|
||||
libeditor::RunnableKind::Test { name } => {
|
||||
vec![
|
||||
"test".to_string(),
|
||||
"--".to_string(),
|
||||
name,
|
||||
"--nocapture".to_string(),
|
||||
]
|
||||
}
|
||||
libeditor::RunnableKind::Bin => vec!["run".to_string()]
|
||||
},
|
||||
env: {
|
||||
let mut m = HashMap::new();
|
||||
m.insert(
|
||||
"RUST_BACKTRACE".to_string(),
|
||||
"short".to_string(),
|
||||
);
|
||||
m
|
||||
}
|
||||
};
|
||||
res.push(r);
|
||||
}
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
pub fn handle_workspace_symbol(
|
||||
world: ServerWorld,
|
||||
params: req::WorkspaceSymbolParams,
|
||||
|
|
|
@ -29,6 +29,7 @@ use {
|
|||
handle_parent_module,
|
||||
handle_join_lines,
|
||||
handle_completion,
|
||||
handle_runnables,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -138,6 +139,9 @@ fn on_request(
|
|||
handle_request_on_threadpool::<req::CodeActionRequest>(
|
||||
&mut req, pool, world, sender, handle_code_action,
|
||||
)?;
|
||||
handle_request_on_threadpool::<req::Runnables>(
|
||||
&mut req, pool, world, sender, handle_runnables,
|
||||
)?;
|
||||
handle_request_on_threadpool::<req::WorkspaceSymbol>(
|
||||
&mut req, pool, world, sender, handle_workspace_symbol,
|
||||
)?;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use serde::{ser::Serialize, de::DeserializeOwned};
|
||||
use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location};
|
||||
use url_serde;
|
||||
|
@ -134,3 +136,28 @@ pub struct JoinLinesParams {
|
|||
pub text_document: TextDocumentIdentifier,
|
||||
pub range: Range,
|
||||
}
|
||||
|
||||
pub enum Runnables {}
|
||||
|
||||
impl Request for Runnables {
|
||||
type Params = RunnablesParams;
|
||||
type Result = Vec<Runnable>;
|
||||
const METHOD: &'static str = "m/joinLines";
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RunnablesParams {
|
||||
pub text_document: TextDocumentIdentifier,
|
||||
pub position: Option<Position>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Runnable {
|
||||
pub range: Range,
|
||||
pub label: String,
|
||||
pub bin: String,
|
||||
pub args: Vec<String>,
|
||||
pub env: HashMap<String, String>,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue