Skip to content

Commit

Permalink
Allow navigation targets to be duplicated when the focus range lies i…
Browse files Browse the repository at this point in the history
…n the macro definition site
  • Loading branch information
Veykril committed Dec 6, 2023
1 parent 9b7ec5e commit 016638a
Show file tree
Hide file tree
Showing 37 changed files with 849 additions and 486 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
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
10 changes: 5 additions & 5 deletions crates/hir/src/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use hir_def::{
};
use hir_expand::{HirFileId, InFile};
use hir_ty::db::HirDatabase;
use syntax::{ast::HasName, AstNode, SmolStr, SyntaxNode, SyntaxNodePtr};
use syntax::{ast::HasName, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr};

use crate::{Module, ModuleDef, Semantics};

Expand All @@ -32,7 +32,7 @@ pub struct DeclarationLocation {
/// This points to the whole syntax node of the declaration.
pub ptr: SyntaxNodePtr,
/// This points to the [`syntax::ast::Name`] identifier of the declaration.
pub name_ptr: SyntaxNodePtr,
pub name_ptr: AstPtr<syntax::ast::Name>,
}

impl DeclarationLocation {
Expand Down Expand Up @@ -185,7 +185,7 @@ impl<'a> SymbolCollector<'a> {
let dec_loc = DeclarationLocation {
hir_file_id: source.file_id,
ptr: SyntaxNodePtr::new(use_tree_src.syntax()),
name_ptr: SyntaxNodePtr::new(name.syntax()),
name_ptr: AstPtr::new(&name),
};

self.symbols.push(FileSymbol {
Expand Down Expand Up @@ -289,7 +289,7 @@ impl<'a> SymbolCollector<'a> {
let dec_loc = DeclarationLocation {
hir_file_id: source.file_id,
ptr: SyntaxNodePtr::new(source.value.syntax()),
name_ptr: SyntaxNodePtr::new(name_node.syntax()),
name_ptr: AstPtr::new(&name_node),
};

if let Some(attrs) = def.attrs(self.db) {
Expand Down Expand Up @@ -322,7 +322,7 @@ impl<'a> SymbolCollector<'a> {
let dec_loc = DeclarationLocation {
hir_file_id: declaration.file_id,
ptr: SyntaxNodePtr::new(module.syntax()),
name_ptr: SyntaxNodePtr::new(name_node.syntax()),
name_ptr: AstPtr::new(&name_node),
};

let def = ModuleDef::Module(module_id.into());
Expand Down

0 comments on commit 016638a

Please sign in to comment.