Skip to content

Commit

Permalink
Auto merge of #16034 - Veykril:ide-macro-improvements, r=Veykril
Browse files Browse the repository at this point in the history
feat: Allow navigation targets to be duplicated when the focus range lies in the macro definition site

![Code_KI1EfbAHRZ](https://github.com/rust-lang/rust-analyzer/assets/3757771/2cc82e5c-320f-4de2-9d55-fe975d180f2a)

Basically if a name of an item originates from the macro definition we now point to that as well as the creating macro call.

Big diff because I also made `FileId`s field private due to some debugging I had to do (having a searchable constructor makes things easier).
  • Loading branch information
bors committed Dec 6, 2023
2 parents 05df6c5 + 9cb13b6 commit cc8faa6
Show file tree
Hide file tree
Showing 38 changed files with 851 additions and 488 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions crates/base-db/src/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl ChangeFixture {

let mut file_set = FileSet::default();
let mut current_source_root_kind = SourceRootKind::Local;
let mut file_id = FileId(0);
let mut file_id = FileId::from_raw(0);
let mut roots = Vec::new();

let mut file_position = None;
Expand Down Expand Up @@ -210,7 +210,7 @@ impl ChangeFixture {
let path = VfsPath::new_virtual_path(meta.path);
file_set.insert(file_id, path);
files.push(file_id);
file_id.0 += 1;
file_id = FileId::from_raw(file_id.index() + 1);
}

if crates.is_empty() {
Expand Down Expand Up @@ -255,7 +255,7 @@ impl ChangeFixture {

if let Some(mini_core) = mini_core {
let core_file = file_id;
file_id.0 += 1;
file_id = FileId::from_raw(file_id.index() + 1);

let mut fs = FileSet::default();
fs.insert(core_file, VfsPath::new_virtual_path("/sysroot/core/lib.rs".to_string()));
Expand Down Expand Up @@ -296,7 +296,6 @@ impl ChangeFixture {
let mut proc_macros = ProcMacros::default();
if !proc_macro_names.is_empty() {
let proc_lib_file = file_id;
file_id.0 += 1;

proc_macro_defs.extend(default_test_proc_macros());
let (proc_macro, source) = filter_test_proc_macros(&proc_macro_names, proc_macro_defs);
Expand Down
20 changes: 10 additions & 10 deletions crates/base-db/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ mod tests {
fn detect_cyclic_dependency_indirect() {
let mut graph = CrateGraph::default();
let crate1 = graph.add_crate_root(
FileId(1u32),
FileId::from_raw(1u32),
Edition2018,
None,
None,
Expand All @@ -893,7 +893,7 @@ mod tests {
None,
);
let crate2 = graph.add_crate_root(
FileId(2u32),
FileId::from_raw(2u32),
Edition2018,
None,
None,
Expand All @@ -906,7 +906,7 @@ mod tests {
None,
);
let crate3 = graph.add_crate_root(
FileId(3u32),
FileId::from_raw(3u32),
Edition2018,
None,
None,
Expand Down Expand Up @@ -942,7 +942,7 @@ mod tests {
fn detect_cyclic_dependency_direct() {
let mut graph = CrateGraph::default();
let crate1 = graph.add_crate_root(
FileId(1u32),
FileId::from_raw(1u32),
Edition2018,
None,
None,
Expand All @@ -955,7 +955,7 @@ mod tests {
None,
);
let crate2 = graph.add_crate_root(
FileId(2u32),
FileId::from_raw(2u32),
Edition2018,
None,
None,
Expand Down Expand Up @@ -985,7 +985,7 @@ mod tests {
fn it_works() {
let mut graph = CrateGraph::default();
let crate1 = graph.add_crate_root(
FileId(1u32),
FileId::from_raw(1u32),
Edition2018,
None,
None,
Expand All @@ -998,7 +998,7 @@ mod tests {
None,
);
let crate2 = graph.add_crate_root(
FileId(2u32),
FileId::from_raw(2u32),
Edition2018,
None,
None,
Expand All @@ -1011,7 +1011,7 @@ mod tests {
None,
);
let crate3 = graph.add_crate_root(
FileId(3u32),
FileId::from_raw(3u32),
Edition2018,
None,
None,
Expand Down Expand Up @@ -1041,7 +1041,7 @@ mod tests {
fn dashes_are_normalized() {
let mut graph = CrateGraph::default();
let crate1 = graph.add_crate_root(
FileId(1u32),
FileId::from_raw(1u32),
Edition2018,
None,
None,
Expand All @@ -1054,7 +1054,7 @@ mod tests {
None,
);
let crate2 = graph.add_crate_root(
FileId(2u32),
FileId::from_raw(2u32),
Edition2018,
None,
None,
Expand Down
20 changes: 7 additions & 13 deletions crates/base-db/src/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl fmt::Debug for SpanAnchor {
}

impl tt::SpanAnchor for SpanAnchor {
const DUMMY: Self = SpanAnchor { file_id: FileId(0), ast_id: ROOT_ERASED_FILE_AST_ID };
const DUMMY: Self = SpanAnchor { file_id: FileId::BOGUS, ast_id: ROOT_ERASED_FILE_AST_ID };
}

/// Input to the analyzer is a set of files, where each file is identified by
Expand Down Expand Up @@ -99,12 +99,6 @@ impl From<HirFileId> for u32 {
}
}

impl From<u32> for HirFileId {
fn from(value: u32) -> Self {
HirFileId(value)
}
}

impl From<MacroCallId> for HirFileId {
fn from(value: MacroCallId) -> Self {
value.as_file()
Expand Down Expand Up @@ -147,7 +141,7 @@ pub enum HirFileIdRepr {
impl fmt::Debug for HirFileIdRepr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::FileId(arg0) => f.debug_tuple("FileId").field(&arg0.0).finish(),
Self::FileId(arg0) => f.debug_tuple("FileId").field(&arg0.index()).finish(),
Self::MacroFile(arg0) => {
f.debug_tuple("MacroFile").field(&arg0.macro_call_id.0).finish()
}
Expand All @@ -156,9 +150,9 @@ impl fmt::Debug for HirFileIdRepr {
}

impl From<FileId> for HirFileId {
fn from(FileId(id): FileId) -> Self {
assert!(id < Self::MAX_FILE_ID);
HirFileId(id)
fn from(id: FileId) -> Self {
assert!(id.index() < Self::MAX_FILE_ID);
HirFileId(id.index())
}
}

Expand Down Expand Up @@ -192,15 +186,15 @@ impl HirFileId {
#[inline]
pub fn file_id(self) -> Option<FileId> {
match self.0 & Self::MACRO_FILE_TAG_MASK {
0 => Some(FileId(self.0)),
0 => Some(FileId::from_raw(self.0)),
_ => None,
}
}

#[inline]
pub fn repr(self) -> HirFileIdRepr {
match self.0 & Self::MACRO_FILE_TAG_MASK {
0 => HirFileIdRepr::FileId(FileId(self.0)),
0 => HirFileIdRepr::FileId(FileId::from_raw(self.0)),
_ => HirFileIdRepr::MacroFile(MacroFileId {
macro_call_id: MacroCallId(InternId::from(self.0 ^ Self::MACRO_FILE_TAG_MASK)),
}),
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/attr/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn assert_parse_result(input: &str, expected: DocExpr) {
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
let tt = syntax_node_to_token_tree(
tt.syntax(),
SpanMapRef::RealSpanMap(&RealSpanMap::absolute(FileId(0))),
SpanMapRef::RealSpanMap(&RealSpanMap::absolute(FileId::from_raw(0))),
);
let cfg = DocExpr::parse(&tt);
assert_eq!(cfg, expected);
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ fn file_id_and_params_of(
(src.file_id, src.value.generic_param_list())
}
// We won't be using this ID anyway
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => (FileId(!0).into(), None),
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => (FileId::BOGUS.into(), None),
}
}

Expand Down
34 changes: 34 additions & 0 deletions crates/hir-expand/src/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,40 @@ impl InFile<TextRange> {
};
range
}

pub fn original_node_file_range(
self,
db: &dyn db::ExpandDatabase,
) -> (FileRange, SyntaxContextId) {
match self.file_id.repr() {
HirFileIdRepr::FileId(file_id) => {
(FileRange { file_id, range: self.value }, SyntaxContextId::ROOT)
}
HirFileIdRepr::MacroFile(mac_file) => {
match ExpansionInfo::new(db, mac_file).map_node_range_up(db, self.value) {
Some(it) => it,
None => {
let loc = db.lookup_intern_macro_call(mac_file.macro_call_id);
(loc.kind.original_call_range(db), SyntaxContextId::ROOT)
}
}
}
}
}

pub fn original_node_file_range_opt(
self,
db: &dyn db::ExpandDatabase,
) -> Option<(FileRange, SyntaxContextId)> {
match self.file_id.repr() {
HirFileIdRepr::FileId(file_id) => {
Some((FileRange { file_id, range: self.value }, SyntaxContextId::ROOT))
}
HirFileIdRepr::MacroFile(mac_file) => {
ExpansionInfo::new(db, mac_file).map_node_range_up(db, self.value)
}
}
}
}

impl<N: AstNode> InFile<N> {
Expand Down
12 changes: 7 additions & 5 deletions crates/hir-expand/src/fixup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ pub(crate) fn fixup_syntax(span_map: SpanMapRef<'_>, node: &SyntaxNode) -> Synta
let dummy_range = TextRange::empty(TextSize::new(0));
// we use a file id of `FileId(!0)` to signal a fake node, and the text range's start offset as
// the index into the replacement vec but only if the end points to !0
let dummy_anchor =
SpanAnchor { file_id: FileId(!0), ast_id: ErasedFileAstId::from_raw(RawIdx::from(!0)) };
let dummy_anchor = SpanAnchor {
file_id: FileId::from_raw(!0),
ast_id: ErasedFileAstId::from_raw(RawIdx::from(!0)),
};
let fake_span = |range| SpanData {
range: dummy_range,
anchor: dummy_anchor,
Expand Down Expand Up @@ -308,7 +310,7 @@ fn reverse_fixups_(tt: &mut Subtree, undo_info: &[Subtree]) {
.filter(|tt| match tt {
tt::TokenTree::Leaf(leaf) => {
let span = leaf.span();
span.anchor.file_id != FileId(!0) || span.range.end() == TextSize::new(!0)
span.anchor.file_id != FileId::from_raw(!0) || span.range.end() == TextSize::new(!0)
}
tt::TokenTree::Subtree(_) => true,
})
Expand All @@ -318,7 +320,7 @@ fn reverse_fixups_(tt: &mut Subtree, undo_info: &[Subtree]) {
SmallVec::from_const([tt.into()])
}
tt::TokenTree::Leaf(leaf) => {
if leaf.span().anchor.file_id == FileId(!0) {
if leaf.span().anchor.file_id == FileId::from_raw(!0) {
let original = undo_info[u32::from(leaf.span().range.start()) as usize].clone();
if original.delimiter.kind == tt::DelimiterKind::Invisible {
original.token_trees.into()
Expand Down Expand Up @@ -373,7 +375,7 @@ mod tests {
#[track_caller]
fn check(ra_fixture: &str, mut expect: Expect) {
let parsed = syntax::SourceFile::parse(ra_fixture);
let span_map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(FileId(0))));
let span_map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(FileId::from_raw(0))));
let fixups = super::fixup_syntax(span_map.as_ref(), &parsed.syntax_node());
let mut tt = mbe::syntax_node_to_token_tree_modified(
&parsed.syntax_node(),
Expand Down
6 changes: 6 additions & 0 deletions crates/hir-expand/src/hygiene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ pub trait SyntaxContextExt {
fn normalize_to_macro_rules(self, db: &dyn ExpandDatabase) -> Self;
fn normalize_to_macros_2_0(self, db: &dyn ExpandDatabase) -> Self;
fn parent_ctxt(self, db: &dyn ExpandDatabase) -> Self;
fn remove_mark(&mut self, db: &dyn ExpandDatabase) -> (Option<MacroCallId>, Transparency);
fn outer_mark(self, db: &dyn ExpandDatabase) -> (Option<MacroCallId>, Transparency);
fn marks(self, db: &dyn ExpandDatabase) -> Vec<(Option<MacroCallId>, Transparency)>;
}
Expand All @@ -223,6 +224,11 @@ impl SyntaxContextExt for SyntaxContextId {
let data = db.lookup_intern_syntax_context(self);
(data.outer_expn, data.outer_transparency)
}
fn remove_mark(&mut self, db: &dyn ExpandDatabase) -> (Option<MacroCallId>, Transparency) {
let data = db.lookup_intern_syntax_context(*self);
*self = data.parent;
(data.outer_expn, data.outer_transparency)
}
fn marks(self, db: &dyn ExpandDatabase) -> Vec<(Option<MacroCallId>, Transparency)> {
let mut marks = marks_rev(self, db).collect::<Vec<_>>();
marks.reverse();
Expand Down
15 changes: 15 additions & 0 deletions crates/hir-expand/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,21 @@ impl MacroDefId {
db.intern_macro_call(MacroCallLoc { def: self, krate, eager: None, kind, call_site })
}

pub fn definition_range(&self, db: &dyn db::ExpandDatabase) -> InFile<TextRange> {
match self.kind {
MacroDefKind::Declarative(id)
| MacroDefKind::BuiltIn(_, id)
| MacroDefKind::BuiltInAttr(_, id)
| MacroDefKind::BuiltInDerive(_, id)
| MacroDefKind::BuiltInEager(_, id) => {
id.with_value(db.ast_id_map(id.file_id).get(id.value).text_range())
}
MacroDefKind::ProcMacro(_, _, id) => {
id.with_value(db.ast_id_map(id.file_id).get(id.value).text_range())
}
}
}

pub fn ast_id(&self) -> Either<AstId<ast::Macro>, AstId<ast::Fn>> {
match self.kind {
MacroDefKind::ProcMacro(.., id) => return Either::Right(id),
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-expand/src/quote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ mod tests {
assert_eq!(quoted.to_string(), "hello");
let t = format!("{quoted:?}");
expect![[r#"
SUBTREE $$ SpanData { range: 0..0, anchor: SpanAnchor(FileId(4294967295), 0), ctx: SyntaxContextId(0) } SpanData { range: 0..0, anchor: SpanAnchor(FileId(4294967295), 0), ctx: SyntaxContextId(0) }
IDENT hello SpanData { range: 0..0, anchor: SpanAnchor(FileId(4294967295), 0), ctx: SyntaxContextId(0) }"#]].assert_eq(&t);
SUBTREE $$ SpanData { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) } SpanData { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) }
IDENT hello SpanData { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) }"#]].assert_eq(&t);
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion crates/hir/src/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ fn modpath_from_str(db: &dyn HirDatabase, link: &str) -> Option<ModPath> {
ModPath::from_src(
db.upcast(),
ast_path,
SpanMapRef::RealSpanMap(&RealSpanMap::absolute(FileId(0))),
SpanMapRef::RealSpanMap(&RealSpanMap::absolute(FileId::BOGUS)),
)
};

Expand Down
1 change: 1 addition & 0 deletions crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ pub use {
},
hir_expand::{
attrs::{Attr, AttrId},
hygiene::{marks_rev, SyntaxContextExt},
name::{known, Name},
tt, ExpandResult, HirFileId, HirFileIdExt, InFile, InMacroFile, InRealFile, MacroFileId,
},
Expand Down
Loading

0 comments on commit cc8faa6

Please sign in to comment.