From 6cade3f6d8ad7bb5a11b1910689b25f709c12502 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Aug 2018 13:41:25 +0300 Subject: [PATCH] Runnig tests somehow --- code/.vscode/launch.json | 3 ++ code/.vscode/tasks.json | 2 +- code/package.json | 26 +++++++++++ code/src/extension.ts | 42 +++++++++++++++++ code/tsconfig.json | 3 +- crates/libeditor/src/typing.rs | 11 +---- crates/libsyntax2/src/algo/mod.rs | 13 ++---- crates/libsyntax2/src/lib.rs | 1 + crates/libsyntax2/src/text_utils.rs | 19 ++++++++ crates/server/src/main_loop/handlers.rs | 61 +++++++++++++++++++++---- 10 files changed, 149 insertions(+), 32 deletions(-) create mode 100644 crates/libsyntax2/src/text_utils.rs diff --git a/code/.vscode/launch.json b/code/.vscode/launch.json index 5e615ad4c3..a5dd523df5 100644 --- a/code/.vscode/launch.json +++ b/code/.vscode/launch.json @@ -10,6 +10,9 @@ "request": "launch", "runtimeExecutable": "${execPath}", "args": ["--extensionDevelopmentPath='./'"], + "env": { + "RUST_LOG": "m=trace" + }, "stopOnEntry": false, "sourceMaps": true, "outFiles": [ "./out/src/**/*.js" ], diff --git a/code/.vscode/tasks.json b/code/.vscode/tasks.json index 8e5a8b9efa..e1cfa4deb6 100644 --- a/code/.vscode/tasks.json +++ b/code/.vscode/tasks.json @@ -21,7 +21,7 @@ "showOutput": "silent", // we run the custom script "compile" as defined in package.json - "args": ["run", "compile", "--loglevel", "silent"], + "args": ["run", "compile",], // The tsc compiler is started in watching mode "isBackground": true, diff --git a/code/package.json b/code/package.json index 20a6ceee76..1ed9dfabe2 100644 --- a/code/package.json +++ b/code/package.json @@ -28,6 +28,28 @@ "onLanguage:rust" ], "contributes": { + "taskDefinitions": [ + { + "type": "cargo", + "required": [ + "command" + ], + "properties": { + "label": { + "type": "string" + }, + "command": { + "type": "string" + }, + "args": { + "type": "array" + }, + "env": { + "type": "object" + } + } + } + ], "commands": [ { "command": "libsyntax-rust.syntaxTree", @@ -48,6 +70,10 @@ { "command": "libsyntax-rust.joinLines", "title": "Rust Join Lines" + }, + { + "command": "libsyntax-rust.run", + "title": "Rust Run" } ], "keybindings": [ diff --git a/code/src/extension.ts b/code/src/extension.ts index df2109f507..c25e8cb611 100644 --- a/code/src/extension.ts +++ b/code/src/extension.ts @@ -81,6 +81,11 @@ export function activate(context: vscode.ExtensionContext) { let e = await vscode.window.showTextDocument(doc) e.revealRange(range, vscode.TextEditorRevealType.InCenter) }) + console.log("ping") + registerCommand('libsyntax-rust.run', async (cmd: ProcessSpec) => { + let task = createTask(cmd) + await vscode.tasks.executeTask(task) + }) dispose(vscode.workspace.registerTextDocumentContentProvider( 'libsyntax-rust', @@ -265,3 +270,40 @@ interface Decoration { range: lc.Range, tag: string, } + +interface ProcessSpec { + bin: string; + args: string[]; + env: { [key: string]: string }; +} + +interface CargoTaskDefinition extends vscode.TaskDefinition { + type: 'cargo'; + label: string; + command: string; + args: Array; + env?: { [key: string]: string }; +} + + +function createTask(spec: ProcessSpec): vscode.Task { + const TASK_SOURCE = 'Rust'; + let definition: CargoTaskDefinition = { + type: 'cargo', + label: 'cargo', + command: spec.bin, + args: spec.args, + env: spec.env + } + + let execCmd = `${definition.command} ${definition.args.join(' ')}`; + let execOption: vscode.ShellExecutionOptions = { + cwd: '.', + env: definition.env, + }; + let exec = new vscode.ShellExecution(execCmd, execOption); + + let f = vscode.workspace.workspaceFolders[0] + let t = new vscode.Task(definition, f, definition.label, TASK_SOURCE, exec, ['$rustc']); + return t; +} diff --git a/code/tsconfig.json b/code/tsconfig.json index 11c3126e00..32a166d0f7 100644 --- a/code/tsconfig.json +++ b/code/tsconfig.json @@ -7,6 +7,5 @@ "sourceMap": true, "rootDir": "." }, - "include": [ "src" ], - "exclude": [ "node_modules" ] + "include": [ "src/*.ts" ], } diff --git a/crates/libeditor/src/typing.rs b/crates/libeditor/src/typing.rs index 04021d1640..cc0d3d272a 100644 --- a/crates/libeditor/src/typing.rs +++ b/crates/libeditor/src/typing.rs @@ -5,6 +5,7 @@ use libsyntax2::{ walk::preorder, find_covering_node, }, + text_utils::intersect, SyntaxKind::*, }; @@ -53,16 +54,6 @@ pub fn join_lines(file: &ast::ParsedFile, range: TextRange) -> ActionResult { } } -fn intersect(r1: TextRange, r2: TextRange) -> Option { - let start = r1.start().max(r2.start()); - let end = r1.end().min(r2.end()); - if start <= end { - Some(TextRange::from_to(start, end)) - } else { - None - } -} - fn remove_newline( edit: &mut EditBuilder, node: SyntaxNodeRef, diff --git a/crates/libsyntax2/src/algo/mod.rs b/crates/libsyntax2/src/algo/mod.rs index 6efdff12f7..2640d60ea0 100644 --- a/crates/libsyntax2/src/algo/mod.rs +++ b/crates/libsyntax2/src/algo/mod.rs @@ -1,7 +1,10 @@ pub mod walk; pub mod visit; -use {SyntaxNodeRef, TextUnit, TextRange}; +use { + SyntaxNodeRef, TextUnit, TextRange, + text_utils::{contains_offset_nonstrict, is_subrange}, +}; pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset { let range = node.range(); @@ -116,14 +119,6 @@ fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNo panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) } -fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { - range.start() <= offset && offset <= range.end() -} - -fn is_subrange(range: TextRange, subrange: TextRange) -> bool { - range.start() <= subrange.start() && subrange.end() <= range.end() -} - fn generate(seed: Option, step: impl Fn(&T) -> Option) -> impl Iterator { ::itertools::unfold(seed, move |slot| { slot.take().map(|curr| { diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs index c078baa3a0..53ae189889 100644 --- a/crates/libsyntax2/src/lib.rs +++ b/crates/libsyntax2/src/lib.rs @@ -39,6 +39,7 @@ mod syntax_kinds; mod yellow; /// Utilities for simple uses of the parser. pub mod utils; +pub mod text_utils; pub use { text_unit::{TextRange, TextUnit}, diff --git a/crates/libsyntax2/src/text_utils.rs b/crates/libsyntax2/src/text_utils.rs new file mode 100644 index 0000000000..e3d73888f4 --- /dev/null +++ b/crates/libsyntax2/src/text_utils.rs @@ -0,0 +1,19 @@ +use {TextRange, TextUnit}; + +pub fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { + range.start() <= offset && offset <= range.end() +} + +pub fn is_subrange(range: TextRange, subrange: TextRange) -> bool { + range.start() <= subrange.start() && subrange.end() <= range.end() +} + +pub fn intersect(r1: TextRange, r2: TextRange) -> Option { + let start = r1.start().max(r2.start()); + let end = r1.end().min(r2.end()); + if start <= end { + Some(TextRange::from_to(start, end)) + } else { + None + } +} diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs index ae362ddaa0..b68e93e46b 100644 --- a/crates/server/src/main_loop/handlers.rs +++ b/crates/server/src/main_loop/handlers.rs @@ -5,10 +5,13 @@ use languageserver_types::{ Command, TextDocumentIdentifier, WorkspaceEdit, SymbolInformation, Position, Location, TextEdit, }; +use serde_json::{to_value, from_value}; use libanalysis::{Query}; use libeditor; -use libsyntax2::TextUnit; -use serde_json::{to_value, from_value}; +use libsyntax2::{ + TextUnit, + text_utils::contains_offset_nonstrict, +}; use ::{ req::{self, Decoration}, Result, @@ -117,7 +120,7 @@ pub fn handle_code_action( let file = world.analysis().file_syntax(file_id)?; let line_index = world.analysis().file_line_index(file_id)?; let offset = params.range.conv_with(&line_index).start(); - let mut ret = Vec::new(); + let mut res = Vec::new(); let actions = &[ (ActionId::FlipComma, libeditor::flip_comma(&file, offset).is_some()), @@ -128,10 +131,52 @@ pub fn handle_code_action( for (id, edit) in actions { if *edit { let cmd = apply_code_action_cmd(*id, params.text_document.clone(), offset); - ret.push(cmd); + res.push(cmd); } } - return Ok(Some(ret)); + for runnable in libeditor::runnables(&file) { + if !contains_offset_nonstrict(runnable.range, offset) { + continue; + } + + #[derive(Serialize)] + struct ProcessSpec { + bin: String, + args: Vec, + env: HashMap, + } + + let spec = ProcessSpec { + 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 + } + }; + + let cmd = Command { + title: "Run ...".to_string(), + command: "libsyntax-rust.run".to_string(), + arguments: Some(vec![to_value(spec).unwrap()]), + }; + res.push(cmd); + } + return Ok(Some(res)); } pub fn handle_workspace_symbol( @@ -257,11 +302,7 @@ struct ActionRequest { } fn apply_code_action_cmd(id: ActionId, doc: TextDocumentIdentifier, offset: TextUnit) -> Command { - let action_request = ActionRequest { - id, - text_document: doc, - offset, - }; + let action_request = ActionRequest { id, text_document: doc, offset }; Command { title: id.title().to_string(), command: "apply_code_action".to_string(),