Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc-macro-srv/src/tests/utils.rs')
-rw-r--r--crates/proc-macro-srv/src/tests/utils.rs71
1 files changed, 70 insertions, 1 deletions
diff --git a/crates/proc-macro-srv/src/tests/utils.rs b/crates/proc-macro-srv/src/tests/utils.rs
index 61fcd810b1..b7c5c4fdd2 100644
--- a/crates/proc-macro-srv/src/tests/utils.rs
+++ b/crates/proc-macro-srv/src/tests/utils.rs
@@ -4,9 +4,11 @@ use expect_test::Expect;
use span::{
EditionedFileId, FileId, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext, TextRange,
};
+use std::ops::Range;
use crate::{
- EnvSnapshot, ProcMacroSrv, SpanId, dylib, proc_macro_test_dylib_path, token_stream::TokenStream,
+ EnvSnapshot, ProcMacroClientInterface, ProcMacroSrv, SpanId, dylib, proc_macro_test_dylib_path,
+ token_stream::TokenStream,
};
fn parse_string(call_site: SpanId, src: &str) -> TokenStream<SpanId> {
@@ -109,3 +111,70 @@ pub(crate) fn list() -> Vec<String> {
let res = srv.list_macros(&dylib_path).unwrap();
res.into_iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect()
}
+
+/// A mock callback for testing that computes line/column from the input text.
+struct MockCallback<'a> {
+ text: &'a str,
+}
+
+impl ProcMacroClientInterface for MockCallback<'_> {
+ fn source_text(&mut self, span: Span) -> Option<String> {
+ self.text
+ .get(usize::from(span.range.start())..usize::from(span.range.end()))
+ .map(ToOwned::to_owned)
+ }
+
+ fn file(&mut self, _file_id: FileId) -> String {
+ String::new()
+ }
+
+ fn local_file(&mut self, _file_id: FileId) -> Option<String> {
+ None
+ }
+
+ fn line_column(&mut self, span: Span) -> Option<(u32, u32)> {
+ let line_index = line_index::LineIndex::new(self.text);
+ let line_col = line_index.try_line_col(span.range.start())?;
+ // proc_macro uses 1-based line/column
+ Some((line_col.line as u32 + 1, line_col.col as u32 + 1))
+ }
+
+ fn byte_range(&mut self, span: Span) -> Range<usize> {
+ Range { start: span.range.start().into(), end: span.range.end().into() }
+ }
+}
+
+pub fn assert_expand_with_callback(
+ macro_name: &str,
+ #[rust_analyzer::rust_fixture] ra_fixture: &str,
+ expect_spanned: Expect,
+) {
+ let path = proc_macro_test_dylib_path();
+ let expander = dylib::Expander::new(&temp_dir::TempDir::new().unwrap(), &path).unwrap();
+
+ let def_site = Span {
+ range: TextRange::new(0.into(), 150.into()),
+ anchor: SpanAnchor {
+ file_id: EditionedFileId::current_edition(FileId::from_raw(41)),
+ ast_id: ROOT_ERASED_FILE_AST_ID,
+ },
+ ctx: SyntaxContext::root(span::Edition::CURRENT),
+ };
+ let call_site = Span {
+ range: TextRange::new(0.into(), 100.into()),
+ anchor: SpanAnchor {
+ file_id: EditionedFileId::current_edition(FileId::from_raw(42)),
+ ast_id: ROOT_ERASED_FILE_AST_ID,
+ },
+ ctx: SyntaxContext::root(span::Edition::CURRENT),
+ };
+ let mixed_site = call_site;
+
+ let fixture = parse_string_spanned(call_site.anchor, call_site.ctx, ra_fixture);
+
+ let mut callback = MockCallback { text: ra_fixture };
+ let res = expander
+ .expand(macro_name, fixture, None, def_site, call_site, mixed_site, Some(&mut callback))
+ .unwrap();
+ expect_spanned.assert_eq(&format!("{res:?}"));
+}