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.rs | 71 |
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:?}")); +} |