about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates/ide
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-11-03 14:18:06 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-11-03 15:35:45 +0100
commit56e89bc5a4c1a37cd073d27dfc16e72d10c08b2e (patch)
treefa78d51be264fe093cfc52549a4c441776bf6a1d /src/tools/rust-analyzer/crates/ide
parent72d9929ccd9daad6687d225a949817eb789e6ff4 (diff)
downloadrust-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.rs64
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/interpret_function.rs47
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs4
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> {