diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2024-11-03 14:18:06 +0100 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2024-11-03 15:35:45 +0100 |
| commit | 56e89bc5a4c1a37cd073d27dfc16e72d10c08b2e (patch) | |
| tree | fa78d51be264fe093cfc52549a4c441776bf6a1d /src/tools/rust-analyzer/crates/ide | |
| parent | 72d9929ccd9daad6687d225a949817eb789e6ff4 (diff) | |
| download | rust-56e89bc5a4c1a37cd073d27dfc16e72d10c08b2e.tar.gz rust-56e89bc5a4c1a37cd073d27dfc16e72d10c08b2e.zip | |
Allow interpreting consts and statics with interpret function command
Diffstat (limited to 'src/tools/rust-analyzer/crates/ide')
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide/src/interpret.rs | 64 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide/src/interpret_function.rs | 47 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide/src/lib.rs | 4 |
3 files changed, 66 insertions, 49 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret.rs b/src/tools/rust-analyzer/crates/ide/src/interpret.rs new file mode 100644 index 00000000000..5abe572a778 --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide/src/interpret.rs @@ -0,0 +1,64 @@ +use hir::{DefWithBody, Semantics}; +use ide_db::{base_db::SourceRootDatabase, FilePosition, LineIndexDatabase, RootDatabase}; +use std::time::{Duration, Instant}; +use stdx::format_to; +use syntax::{algo::ancestors_at_offset, ast, AstNode, TextRange}; + +// Feature: Interpret a function, static or const. +// +// |=== +// | Editor | Action Name +// +// | VS Code | **rust-analyzer: Interpret** +// |=== +pub(crate) fn interpret(db: &RootDatabase, position: FilePosition) -> String { + match find_and_interpret(db, position) { + Some((duration, mut result)) => { + result.push('\n'); + format_to!(result, "----------------------\n"); + format_to!(result, " Finished in {}s\n", duration.as_secs_f32()); + result + } + _ => "Not inside a function, const or static".to_owned(), + } +} + +fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<(Duration, String)> { + let sema = Semantics::new(db); + let source_file = sema.parse_guess_edition(position.file_id); + + let item = ancestors_at_offset(source_file.syntax(), position.offset) + .filter(|it| !ast::MacroCall::can_cast(it.kind())) + .find_map(ast::Item::cast)?; + let def: DefWithBody = match item { + ast::Item::Fn(it) => sema.to_def(&it)?.into(), + ast::Item::Const(it) => sema.to_def(&it)?.into(), + ast::Item::Static(it) => sema.to_def(&it)?.into(), + _ => return None, + }; + let span_formatter = |file_id, text_range: TextRange| { + let path = &db + .source_root(db.file_source_root(file_id)) + .path_for_file(&file_id) + .map(|x| x.to_string()); + let path = path.as_deref().unwrap_or("<unknown file>"); + match db.line_index(file_id).try_line_col(text_range.start()) { + Some(line_col) => format!("file://{path}:{}:{}", line_col.line + 1, line_col.col), + None => format!("file://{path} range {text_range:?}"), + } + }; + let start_time = Instant::now(); + let res = match def { + DefWithBody::Function(it) => it.eval(db, span_formatter), + DefWithBody::Static(it) => it.eval(db), + DefWithBody::Const(it) => it.eval(db), + _ => unreachable!(), + }; + let res = res.unwrap_or_else(|e| { + let mut r = String::new(); + _ = e.pretty_print(&mut r, db, span_formatter, def.module(db).krate().edition(db)); + r + }); + let duration = Instant::now() - start_time; + Some((duration, res)) +} diff --git a/src/tools/rust-analyzer/crates/ide/src/interpret_function.rs b/src/tools/rust-analyzer/crates/ide/src/interpret_function.rs deleted file mode 100644 index ff1317d135c..00000000000 --- a/src/tools/rust-analyzer/crates/ide/src/interpret_function.rs +++ /dev/null @@ -1,47 +0,0 @@ -use hir::Semantics; -use ide_db::{base_db::SourceRootDatabase, FilePosition, LineIndexDatabase, RootDatabase}; -use std::{fmt::Write, time::Instant}; -use syntax::{algo::ancestors_at_offset, ast, AstNode, TextRange}; - -// Feature: Interpret Function -// -// |=== -// | Editor | Action Name -// -// | VS Code | **rust-analyzer: Interpret Function** -// |=== -pub(crate) fn interpret_function(db: &RootDatabase, position: FilePosition) -> String { - let start_time = Instant::now(); - let mut result = - find_and_interpret(db, position).unwrap_or_else(|| "Not inside a function body".to_owned()); - let duration = Instant::now() - start_time; - writeln!(result).unwrap(); - writeln!(result, "----------------------").unwrap(); - writeln!(result, " Finished in {}s", duration.as_secs_f32()).unwrap(); - result -} - -fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<String> { - let sema = Semantics::new(db); - let source_file = sema.parse_guess_edition(position.file_id); - - let item = ancestors_at_offset(source_file.syntax(), position.offset) - .filter(|it| !ast::MacroCall::can_cast(it.kind())) - .find_map(ast::Item::cast)?; - let def = match item { - ast::Item::Fn(it) => sema.to_def(&it)?, - _ => return None, - }; - let span_formatter = |file_id, text_range: TextRange| { - let path = &db - .source_root(db.file_source_root(file_id)) - .path_for_file(&file_id) - .map(|x| x.to_string()); - let path = path.as_deref().unwrap_or("<unknown file>"); - match db.line_index(file_id).try_line_col(text_range.start()) { - Some(line_col) => format!("file://{path}#{}:{}", line_col.line + 1, line_col.col), - None => format!("file://{path} range {text_range:?}"), - } - }; - Some(def.eval(db, span_formatter)) -} diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs index d053c4b3c93..d4ef9570e1a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/lib.rs +++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs @@ -33,7 +33,7 @@ mod goto_type_definition; mod highlight_related; mod hover; mod inlay_hints; -mod interpret_function; +mod interpret; mod join_lines; mod markdown_remove; mod matching_brace; @@ -350,7 +350,7 @@ impl Analysis { } pub fn interpret_function(&self, position: FilePosition) -> Cancellable<String> { - self.with_db(|db| interpret_function::interpret_function(db, position)) + self.with_db(|db| interpret::interpret(db, position)) } pub fn view_item_tree(&self, file_id: FileId) -> Cancellable<String> { |
