mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-02 04:48:13 +00:00
Support spans with proc macro servers from before the ast id changes
The only thing changed is the value of the fixup ast id, so we just swap it.
This commit is contained in:
parent
c15fc9a344
commit
3e834add61
10 changed files with 96 additions and 102 deletions
|
|
@ -12,13 +12,13 @@ pub mod legacy_protocol {
|
|||
mod process;
|
||||
|
||||
use paths::{AbsPath, AbsPathBuf};
|
||||
use span::Span;
|
||||
use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span};
|
||||
use std::{fmt, io, sync::Arc, time::SystemTime};
|
||||
|
||||
use crate::{
|
||||
legacy_protocol::msg::{
|
||||
ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, HAS_GLOBAL_SPANS, PanicMessage,
|
||||
RUST_ANALYZER_SPAN_SUPPORT, Request, Response, SpanDataIndexMap,
|
||||
ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, HAS_GLOBAL_SPANS, HASHED_AST_ID,
|
||||
PanicMessage, RUST_ANALYZER_SPAN_SUPPORT, Request, Response, SpanDataIndexMap,
|
||||
deserialize_span_data_index_map, flat::serialize_span_data_index_map,
|
||||
},
|
||||
process::ProcMacroServerProcess,
|
||||
|
|
@ -161,6 +161,38 @@ impl ProcMacro {
|
|||
self.kind
|
||||
}
|
||||
|
||||
fn needs_fixup_change(&self) -> bool {
|
||||
let version = self.process.version();
|
||||
(RUST_ANALYZER_SPAN_SUPPORT..HASHED_AST_ID).contains(&version)
|
||||
}
|
||||
|
||||
/// On some server versions, the fixup ast id is different than ours. So change it to match.
|
||||
fn change_fixup_to_match_old_server(&self, tt: &mut tt::TopSubtree<Span>) {
|
||||
const OLD_FIXUP_AST_ID: ErasedFileAstId = ErasedFileAstId::from_raw(!0 - 1);
|
||||
let change_ast_id = |ast_id: &mut ErasedFileAstId| {
|
||||
if *ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER {
|
||||
*ast_id = OLD_FIXUP_AST_ID;
|
||||
} else if *ast_id == OLD_FIXUP_AST_ID {
|
||||
// Swap between them, that means no collision plus the change can be reversed by doing itself.
|
||||
*ast_id = FIXUP_ERASED_FILE_AST_ID_MARKER;
|
||||
}
|
||||
};
|
||||
|
||||
for tt in &mut tt.0 {
|
||||
match tt {
|
||||
tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { span, .. }))
|
||||
| tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { span, .. }))
|
||||
| tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { span, .. })) => {
|
||||
change_ast_id(&mut span.anchor.ast_id);
|
||||
}
|
||||
tt::TokenTree::Subtree(subtree) => {
|
||||
change_ast_id(&mut subtree.delimiter.open.anchor.ast_id);
|
||||
change_ast_id(&mut subtree.delimiter.close.anchor.ast_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Expands the procedural macro by sending an expansion request to the server.
|
||||
/// This includes span information and environmental context.
|
||||
pub fn expand(
|
||||
|
|
@ -173,6 +205,20 @@ impl ProcMacro {
|
|||
mixed_site: Span,
|
||||
current_dir: String,
|
||||
) -> Result<Result<tt::TopSubtree<Span>, PanicMessage>, ServerError> {
|
||||
let (mut subtree, mut attr) = (subtree, attr);
|
||||
let (mut subtree_changed, mut attr_changed);
|
||||
if self.needs_fixup_change() {
|
||||
subtree_changed = tt::TopSubtree::from_subtree(subtree);
|
||||
self.change_fixup_to_match_old_server(&mut subtree_changed);
|
||||
subtree = subtree_changed.view();
|
||||
|
||||
if let Some(attr) = &mut attr {
|
||||
attr_changed = tt::TopSubtree::from_subtree(*attr);
|
||||
self.change_fixup_to_match_old_server(&mut attr_changed);
|
||||
*attr = attr_changed.view();
|
||||
}
|
||||
}
|
||||
|
||||
let version = self.process.version();
|
||||
|
||||
let mut span_data_table = SpanDataIndexMap::default();
|
||||
|
|
@ -205,15 +251,23 @@ impl ProcMacro {
|
|||
let response = self.process.send_task(Request::ExpandMacro(Box::new(task)))?;
|
||||
|
||||
match response {
|
||||
Response::ExpandMacro(it) => {
|
||||
Ok(it.map(|tree| FlatTree::to_subtree_resolved(tree, version, &span_data_table)))
|
||||
}
|
||||
Response::ExpandMacro(it) => Ok(it.map(|tree| {
|
||||
let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table);
|
||||
if self.needs_fixup_change() {
|
||||
self.change_fixup_to_match_old_server(&mut expanded);
|
||||
}
|
||||
expanded
|
||||
})),
|
||||
Response::ExpandMacroExtended(it) => Ok(it.map(|resp| {
|
||||
FlatTree::to_subtree_resolved(
|
||||
let mut expanded = FlatTree::to_subtree_resolved(
|
||||
resp.tree,
|
||||
version,
|
||||
&deserialize_span_data_index_map(&resp.span_data_table),
|
||||
)
|
||||
);
|
||||
if self.needs_fixup_change() {
|
||||
self.change_fixup_to_match_old_server(&mut expanded);
|
||||
}
|
||||
expanded
|
||||
})),
|
||||
_ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue