Merge pull request #21400 from Veykril/push-kslvlxlpmwwu
internal: Clean up proc-macro-srv callback trait
This commit is contained in:
commit
4bfdbb8bba
8 changed files with 58 additions and 61 deletions
|
|
@ -26,6 +26,9 @@ const _: () = {
|
|||
krate: Crate,
|
||||
}
|
||||
|
||||
// FIXME: This poses an invalidation problem, if one constructs an `EditionedFileId` with a
|
||||
// different crate then whatever the input of a memo used, it will invalidate the memo causing
|
||||
// it to recompute even if the crate is not really used.
|
||||
/// We like to include the origin crate in an `EditionedFileId` (for use in the item tree),
|
||||
/// but this poses us a problem.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ use triomphe::Arc;
|
|||
|
||||
use crate::{
|
||||
AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo,
|
||||
EagerExpander, EditionedFileId, ExpandError, ExpandResult, ExpandTo, HirFileId, MacroCallId,
|
||||
MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
|
||||
EagerExpander, EditionedFileId, ExpandError, ExpandResult, ExpandTo, FileRange, HirFileId,
|
||||
MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
|
||||
attrs::Meta,
|
||||
builtin::pseudo_derive_attr_expansion,
|
||||
cfg_process::attr_macro_input_to_token_tree,
|
||||
|
|
@ -61,6 +61,9 @@ pub trait ExpandDatabase: RootQueryDb {
|
|||
#[salsa::lru(1024)]
|
||||
fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>;
|
||||
|
||||
#[salsa::transparent]
|
||||
fn resolve_span(&self, span: Span) -> FileRange;
|
||||
|
||||
#[salsa::transparent]
|
||||
fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode;
|
||||
|
||||
|
|
@ -158,6 +161,13 @@ fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId, edition: Edition) ->
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_span(db: &dyn ExpandDatabase, Span { range, anchor, ctx: _ }: Span) -> FileRange {
|
||||
let file_id = EditionedFileId::from_span_guess_origin(db, anchor.file_id);
|
||||
let anchor_offset =
|
||||
db.ast_id_map(file_id.into()).get_erased(anchor.ast_id).text_range().start();
|
||||
FileRange { file_id, range: range + anchor_offset }
|
||||
}
|
||||
|
||||
/// This expands the given macro call, but with different arguments. This is
|
||||
/// used for completion, where we want to see what 'would happen' if we insert a
|
||||
/// token. The `token_to_map` mapped down into the expansion, with the mapped
|
||||
|
|
|
|||
|
|
@ -901,11 +901,8 @@ impl ExpansionInfo {
|
|||
let span = self.exp_map.span_at(token.start());
|
||||
match &self.arg_map {
|
||||
SpanMap::RealSpanMap(_) => {
|
||||
let file_id =
|
||||
EditionedFileId::from_span_guess_origin(db, span.anchor.file_id).into();
|
||||
let anchor_offset =
|
||||
db.ast_id_map(file_id).get_erased(span.anchor.ast_id).text_range().start();
|
||||
InFile { file_id, value: smallvec::smallvec![span.range + anchor_offset] }
|
||||
let range = db.resolve_span(span);
|
||||
InFile { file_id: range.file_id.into(), value: smallvec::smallvec![range.range] }
|
||||
}
|
||||
SpanMap::ExpansionSpanMap(arg_map) => {
|
||||
let Some(arg_node) = &self.arg.value else {
|
||||
|
|
@ -947,7 +944,7 @@ pub fn map_node_range_up_rooted(
|
|||
range: TextRange,
|
||||
) -> Option<FileRange> {
|
||||
let mut spans = exp_map.spans_for_range(range).filter(|span| span.ctx.is_root());
|
||||
let Span { range, anchor, ctx: _ } = spans.next()?;
|
||||
let Span { range, anchor, ctx } = spans.next()?;
|
||||
let mut start = range.start();
|
||||
let mut end = range.end();
|
||||
|
||||
|
|
@ -958,10 +955,7 @@ pub fn map_node_range_up_rooted(
|
|||
start = start.min(span.range.start());
|
||||
end = end.max(span.range.end());
|
||||
}
|
||||
let file_id = EditionedFileId::from_span_guess_origin(db, anchor.file_id);
|
||||
let anchor_offset =
|
||||
db.ast_id_map(file_id.into()).get_erased(anchor.ast_id).text_range().start();
|
||||
Some(FileRange { file_id, range: TextRange::new(start, end) + anchor_offset })
|
||||
Some(db.resolve_span(Span { range: TextRange::new(start, end), anchor, ctx }))
|
||||
}
|
||||
|
||||
/// Maps up the text range out of the expansion hierarchy back into the original file its from.
|
||||
|
|
@ -984,10 +978,7 @@ pub fn map_node_range_up(
|
|||
start = start.min(span.range.start());
|
||||
end = end.max(span.range.end());
|
||||
}
|
||||
let file_id = EditionedFileId::from_span_guess_origin(db, anchor.file_id);
|
||||
let anchor_offset =
|
||||
db.ast_id_map(file_id.into()).get_erased(anchor.ast_id).text_range().start();
|
||||
Some((FileRange { file_id, range: TextRange::new(start, end) + anchor_offset }, ctx))
|
||||
Some((db.resolve_span(Span { range: TextRange::new(start, end), anchor, ctx }), ctx))
|
||||
}
|
||||
|
||||
/// Looks up the span at the given offset.
|
||||
|
|
@ -997,10 +988,7 @@ pub fn span_for_offset(
|
|||
offset: TextSize,
|
||||
) -> (FileRange, SyntaxContext) {
|
||||
let span = exp_map.span_at(offset);
|
||||
let file_id = EditionedFileId::from_span_guess_origin(db, span.anchor.file_id);
|
||||
let anchor_offset =
|
||||
db.ast_id_map(file_id.into()).get_erased(span.anchor.ast_id).text_range().start();
|
||||
(FileRange { file_id, range: span.range + anchor_offset }, span.ctx)
|
||||
(db.resolve_span(span), span.ctx)
|
||||
}
|
||||
|
||||
/// In Rust, macros expand token trees to token trees. When we want to turn a
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use hir_expand::{
|
|||
},
|
||||
};
|
||||
use ide_db::{
|
||||
ChangeWithProcMacros, EditionedFileId, FxHashMap, RootDatabase,
|
||||
ChangeWithProcMacros, FxHashMap, RootDatabase,
|
||||
base_db::{CrateGraphBuilder, Env, ProcMacroLoadingError, SourceRoot, SourceRootId},
|
||||
prime_caches,
|
||||
};
|
||||
|
|
@ -32,7 +32,8 @@ use proc_macro_api::{
|
|||
},
|
||||
};
|
||||
use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace};
|
||||
use span::Span;
|
||||
use span::{Span, SpanAnchor, SyntaxContext};
|
||||
use tt::{TextRange, TextSize};
|
||||
use vfs::{
|
||||
AbsPath, AbsPathBuf, FileId, VfsPath,
|
||||
file_set::FileSetConfig,
|
||||
|
|
@ -553,20 +554,18 @@ impl ProcMacroExpander for Expander {
|
|||
Ok(SubResponse::LocalFilePathResult { name })
|
||||
}
|
||||
SubRequest::SourceText { file_id, ast_id, start, end } => {
|
||||
let raw_file_id = FileId::from_raw(file_id);
|
||||
let editioned_file_id = span::EditionedFileId::from_raw(file_id);
|
||||
let ast_id = span::ErasedFileAstId::from_raw(ast_id);
|
||||
let hir_file_id = EditionedFileId::from_span_guess_origin(db, editioned_file_id);
|
||||
let anchor_offset = db
|
||||
.ast_id_map(hir_expand::HirFileId::FileId(hir_file_id))
|
||||
.get_erased(ast_id)
|
||||
.text_range()
|
||||
.start();
|
||||
let anchor_offset = u32::from(anchor_offset);
|
||||
let abs_start = start + anchor_offset;
|
||||
let abs_end = end + anchor_offset;
|
||||
let source = db.file_text(raw_file_id).text(db);
|
||||
let text = source.get(abs_start as usize..abs_end as usize).map(ToOwned::to_owned);
|
||||
let editioned_file_id = span::EditionedFileId::from_raw(file_id);
|
||||
let span = Span {
|
||||
range: TextRange::new(TextSize::from(start), TextSize::from(end)),
|
||||
anchor: SpanAnchor { file_id: editioned_file_id, ast_id },
|
||||
ctx: SyntaxContext::root(editioned_file_id.edition()),
|
||||
};
|
||||
let range = db.resolve_span(span);
|
||||
let source = db.file_text(range.file_id.file_id(db)).text(db);
|
||||
let text = source
|
||||
.get(usize::from(range.range.start())..usize::from(range.range.end()))
|
||||
.map(ToOwned::to_owned);
|
||||
|
||||
Ok(SubResponse::SourceTextResult { text })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ clap = {version = "4.5.42", default-features = false, features = ["std"]}
|
|||
|
||||
[features]
|
||||
default = []
|
||||
# default = ["sysroot-abi"]
|
||||
sysroot-abi = ["proc-macro-srv/sysroot-abi", "proc-macro-api/sysroot-abi"]
|
||||
in-rust-tree = ["proc-macro-srv/in-rust-tree", "sysroot-abi"]
|
||||
|
||||
|
|
|
|||
|
|
@ -185,8 +185,8 @@ impl<'a, C: Codec> ProcMacroClientHandle<'a, C> {
|
|||
}
|
||||
|
||||
impl<C: Codec> proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> {
|
||||
fn file(&mut self, file_id: u32) -> String {
|
||||
match self.roundtrip(bidirectional::SubRequest::FilePath { file_id }) {
|
||||
fn file(&mut self, file_id: proc_macro_srv::span::FileId) -> String {
|
||||
match self.roundtrip(bidirectional::SubRequest::FilePath { file_id: file_id.index() }) {
|
||||
Some(bidirectional::BidirectionalMessage::SubResponse(
|
||||
bidirectional::SubResponse::FilePathResult { name },
|
||||
)) => name,
|
||||
|
|
@ -194,9 +194,16 @@ impl<C: Codec> proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl
|
|||
}
|
||||
}
|
||||
|
||||
fn source_text(&mut self, file_id: u32, ast_id: u32, start: u32, end: u32) -> Option<String> {
|
||||
match self.roundtrip(bidirectional::SubRequest::SourceText { file_id, ast_id, start, end })
|
||||
{
|
||||
fn source_text(
|
||||
&mut self,
|
||||
proc_macro_srv::span::Span { range, anchor, ctx: _ }: proc_macro_srv::span::Span,
|
||||
) -> Option<String> {
|
||||
match self.roundtrip(bidirectional::SubRequest::SourceText {
|
||||
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::SourceTextResult { text },
|
||||
)) => text,
|
||||
|
|
@ -204,8 +211,9 @@ impl<C: Codec> proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl
|
|||
}
|
||||
}
|
||||
|
||||
fn local_file(&mut self, file_id: u32) -> Option<String> {
|
||||
match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id }) {
|
||||
fn local_file(&mut self, file_id: proc_macro_srv::span::FileId) -> Option<String> {
|
||||
match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id: file_id.index() })
|
||||
{
|
||||
Some(bidirectional::BidirectionalMessage::SubResponse(
|
||||
bidirectional::SubResponse::LocalFilePathResult { name },
|
||||
)) => name,
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ use temp_dir::TempDir;
|
|||
pub use crate::server_impl::token_id::SpanId;
|
||||
|
||||
pub use proc_macro::Delimiter;
|
||||
pub use span;
|
||||
|
||||
pub use crate::bridge::*;
|
||||
pub use crate::server_impl::literal_from_str;
|
||||
|
|
@ -94,9 +95,9 @@ impl<'env> ProcMacroSrv<'env> {
|
|||
pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send);
|
||||
|
||||
pub trait ProcMacroClientInterface {
|
||||
fn file(&mut self, file_id: u32) -> String;
|
||||
fn source_text(&mut self, file_id: u32, ast_id: u32, start: u32, end: u32) -> Option<String>;
|
||||
fn local_file(&mut self, file_id: u32) -> Option<String>;
|
||||
fn file(&mut self, file_id: span::FileId) -> String;
|
||||
fn source_text(&mut self, span: Span) -> Option<String>;
|
||||
fn local_file(&mut self, file_id: span::FileId) -> Option<String>;
|
||||
}
|
||||
|
||||
const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024;
|
||||
|
|
|
|||
|
|
@ -128,13 +128,10 @@ impl server::Span for RaSpanServer<'_> {
|
|||
format!("{:?}", span)
|
||||
}
|
||||
fn file(&mut self, span: Self::Span) -> String {
|
||||
self.callback
|
||||
.as_mut()
|
||||
.map(|cb| cb.file(span.anchor.file_id.file_id().index()))
|
||||
.unwrap_or_default()
|
||||
self.callback.as_mut().map(|cb| cb.file(span.anchor.file_id.file_id())).unwrap_or_default()
|
||||
}
|
||||
fn local_file(&mut self, span: Self::Span) -> Option<String> {
|
||||
self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id().index()))
|
||||
self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id()))
|
||||
}
|
||||
fn save_span(&mut self, _span: Self::Span) -> usize {
|
||||
// FIXME, quote is incompatible with third-party tools
|
||||
|
|
@ -153,17 +150,7 @@ impl server::Span for RaSpanServer<'_> {
|
|||
/// See PR:
|
||||
/// https://github.com/rust-lang/rust/pull/55780
|
||||
fn source_text(&mut self, span: Self::Span) -> Option<String> {
|
||||
let file_id = span.anchor.file_id;
|
||||
let ast_id = span.anchor.ast_id;
|
||||
let start: u32 = span.range.start().into();
|
||||
let end: u32 = span.range.end().into();
|
||||
|
||||
self.callback.as_mut()?.source_text(
|
||||
file_id.file_id().index(),
|
||||
ast_id.into_raw(),
|
||||
start,
|
||||
end,
|
||||
)
|
||||
self.callback.as_mut()?.source_text(span)
|
||||
}
|
||||
|
||||
fn parent(&mut self, _span: Self::Span) -> Option<Self::Span> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue