diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs index 33468a5003c3..8342492a33a4 100644 --- a/crates/load-cargo/src/lib.rs +++ b/crates/load-cargo/src/lib.rs @@ -553,6 +553,7 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::LocalFilePathResult { name }) } + // Not incremental: requires full file text. SubRequest::SourceText { file_id, ast_id, start, end } => { let range = resolve_sub_span( db, @@ -567,6 +568,7 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::SourceTextResult { text }) } + // Not incremental: requires building line index. SubRequest::LineColumn { file_id, ast_id, offset } => { let range = resolve_sub_span(db, file_id, ast_id, TextRange::empty(TextSize::from(offset))); @@ -591,6 +593,17 @@ impl ProcMacroExpander for Expander { Ok(SubResponse::FilePathResult { name }) } + // Not incremental: requires global span resolution. + SubRequest::ByteRange { file_id, ast_id, start, end } => { + let range = resolve_sub_span( + db, + file_id, + ast_id, + TextRange::new(TextSize::from(start), TextSize::from(end)), + ); + + Ok(SubResponse::ByteRangeResult { range: range.range.into() }) + } }; match self.0.expand( subtree.view(), diff --git a/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 0e3b700dcc5a..57e7b1ee8f68 100644 --- a/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -1,5 +1,7 @@ //! Bidirectional protocol messages +use std::ops::Range; + use paths::Utf8PathBuf; use serde::{Deserialize, Serialize}; @@ -14,6 +16,7 @@ pub enum SubRequest { SourceText { file_id: u32, ast_id: u32, start: u32, end: u32 }, LocalFilePath { file_id: u32 }, LineColumn { file_id: u32, ast_id: u32, offset: u32 }, + ByteRange { file_id: u32, ast_id: u32, start: u32, end: u32 }, } #[derive(Debug, Serialize, Deserialize)] @@ -32,6 +35,9 @@ pub enum SubResponse { line: u32, column: u32, }, + ByteRangeResult { + range: Range, + }, } #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs index 0c651d22b41b..3beaeb0697ec 100644 --- a/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/crates/proc-macro-srv-cli/src/main_loop.rs @@ -6,7 +6,10 @@ use proc_macro_api::{ transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version::CURRENT_API_VERSION, }; -use std::io::{self, BufRead, Write}; +use std::{ + io::{self, BufRead, Write}, + ops::Range, +}; use legacy::Message; @@ -240,6 +243,23 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl _ => None, } } + + fn byte_range( + &mut self, + proc_macro_srv::span::Span { range, anchor, ctx: _ }: proc_macro_srv::span::Span, + ) -> Range { + match self.roundtrip(bidirectional::SubRequest::ByteRange { + file_id: anchor.file_id.as_u32(), + ast_id: anchor.ast_id.into_raw(), + start: range.start().into(), + end: range.end().into(), + }) { + Some(bidirectional::BidirectionalMessage::SubResponse( + bidirectional::SubResponse::ByteRangeResult { range }, + )) => range, + _ => Range { start: range.start().into(), end: range.end().into() }, + } + } } fn handle_expand_ra( diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index c1ef49a7176b..ac9f89352c2b 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -41,6 +41,7 @@ use std::{ env, ffi::OsString, fs, + ops::Range, path::{Path, PathBuf}, sync::{Arc, Mutex, PoisonError}, thread, @@ -100,6 +101,8 @@ pub trait ProcMacroClientInterface { fn local_file(&mut self, file_id: span::FileId) -> Option; /// Line and column are 1-based. fn line_column(&mut self, span: Span) -> Option<(u32, u32)>; + + fn byte_range(&mut self, span: Span) -> Range; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; diff --git a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 3a25391b573b..9946608247c3 100644 --- a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -162,7 +162,10 @@ impl server::Span for RaSpanServer<'_> { span } fn byte_range(&mut self, span: Self::Span) -> Range { - // FIXME requires db to resolve the ast id, THIS IS NOT INCREMENTAL + if let Some(cb) = self.callback.as_mut() { + return cb.byte_range(span); + } + Range { start: span.range.start().into(), end: span.range.end().into() } } fn join(&mut self, first: Self::Span, second: Self::Span) -> Option { diff --git a/crates/proc-macro-srv/src/tests/utils.rs b/crates/proc-macro-srv/src/tests/utils.rs index 81ff1965d68b..b7c5c4fdd21f 100644 --- a/crates/proc-macro-srv/src/tests/utils.rs +++ b/crates/proc-macro-srv/src/tests/utils.rs @@ -4,6 +4,7 @@ use expect_test::Expect; use span::{ EditionedFileId, FileId, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext, TextRange, }; +use std::ops::Range; use crate::{ EnvSnapshot, ProcMacroClientInterface, ProcMacroSrv, SpanId, dylib, proc_macro_test_dylib_path, @@ -137,6 +138,10 @@ impl ProcMacroClientInterface for MockCallback<'_> { // 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 { + Range { start: span.range.start().into(), end: span.range.end().into() } + } } pub fn assert_expand_with_callback(