Auto merge of #16703 - regexident:sema-ast-to-hir, r=Veykril

Add more methods for resolving definitions from AST to their corresponding HIR types

In order to be able to add these methods with consistent naming I had to also rename two existing methods that would otherwise be conflicting/confusing:

`Semantics::to_module_def(&self, file: FileId) -> Option<Module>` (before)
`Semantics::file_to_module_def(&self, file: FileId) -> Option<Module>` (after)

`Semantics::to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module>` (before)
`Semantics::file_to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module>` (after)

(the PR is motivated by an outside use of the `ra_ap_hir` crate that would benefit from being able to walk a `hir::Function`'s AST, resolving its exprs/stmts/items to their HIR equivalents)
This commit is contained in:
bors 2024-03-04 09:02:32 +00:00
commit d8feb908be
12 changed files with 71 additions and 22 deletions

View File

@ -38,10 +38,11 @@
db::HirDatabase,
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
source_analyzer::{resolve_hir_path, SourceAnalyzer},
Access, Adjust, Adjustment, AutoBorrow, BindingMode, BuiltinAttr, Callable, ConstParam, Crate,
DeriveHelper, Field, Function, HasSource, HirFileId, Impl, InFile, Label, LifetimeParam, Local,
Macro, Module, ModuleDef, Name, OverloadedDeref, Path, ScopeDef, Struct, ToolModule, Trait,
TupleField, Type, TypeAlias, TypeParam, VariantDef,
Access, Adjust, Adjustment, Adt, AutoBorrow, BindingMode, BuiltinAttr, Callable, Const,
ConstParam, Crate, DeriveHelper, Enum, Field, Function, HasSource, HirFileId, Impl, InFile,
Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, OverloadedDeref, Path, ScopeDef,
Static, Struct, ToolModule, Trait, TraitAlias, TupleField, Type, TypeAlias, TypeParam, Union,
Variant, VariantDef,
};
pub enum DescendPreference {
@ -223,20 +224,68 @@ pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantDef>
self.imp.resolve_variant(record_lit).map(VariantDef::from)
}
pub fn to_module_def(&self, file: FileId) -> Option<Module> {
self.imp.to_module_def(file).next()
pub fn file_to_module_def(&self, file: FileId) -> Option<Module> {
self.imp.file_to_module_defs(file).next()
}
pub fn to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module> {
self.imp.to_module_def(file)
pub fn file_to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module> {
self.imp.file_to_module_defs(file)
}
pub fn to_adt_def(&self, a: &ast::Adt) -> Option<Adt> {
self.imp.to_def(a).map(Adt::from)
}
pub fn to_const_def(&self, c: &ast::Const) -> Option<Const> {
self.imp.to_def(c).map(Const::from)
}
pub fn to_enum_def(&self, e: &ast::Enum) -> Option<Enum> {
self.imp.to_def(e).map(Enum::from)
}
pub fn to_enum_variant_def(&self, v: &ast::Variant) -> Option<Variant> {
self.imp.to_def(v).map(Variant::from)
}
pub fn to_fn_def(&self, f: &ast::Fn) -> Option<Function> {
self.imp.to_def(f).map(Function::from)
}
pub fn to_impl_def(&self, i: &ast::Impl) -> Option<Impl> {
self.imp.to_def(i).map(Impl::from)
}
pub fn to_macro_def(&self, m: &ast::Macro) -> Option<Macro> {
self.imp.to_def(m).map(Macro::from)
}
pub fn to_module_def(&self, m: &ast::Module) -> Option<Module> {
self.imp.to_def(m).map(Module::from)
}
pub fn to_static_def(&self, s: &ast::Static) -> Option<Static> {
self.imp.to_def(s).map(Static::from)
}
pub fn to_struct_def(&self, s: &ast::Struct) -> Option<Struct> {
self.imp.to_def(s).map(Struct::from)
}
pub fn to_impl_def(&self, i: &ast::Impl) -> Option<Impl> {
self.imp.to_def(i).map(Impl::from)
pub fn to_trait_alias_def(&self, t: &ast::TraitAlias) -> Option<TraitAlias> {
self.imp.to_def(t).map(TraitAlias::from)
}
pub fn to_trait_def(&self, t: &ast::Trait) -> Option<Trait> {
self.imp.to_def(t).map(Trait::from)
}
pub fn to_type_alias_def(&self, t: &ast::TypeAlias) -> Option<TypeAlias> {
self.imp.to_def(t).map(TypeAlias::from)
}
pub fn to_union_def(&self, u: &ast::Union) -> Option<Union> {
self.imp.to_def(u).map(Union::from)
}
}
@ -1241,7 +1290,7 @@ pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
T::to_def(self, src)
}
fn to_module_def(&self, file: FileId) -> impl Iterator<Item = Module> {
fn file_to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module> {
self.with_ctx(|ctx| ctx.file_to_def(file)).into_iter().map(Module::from)
}

View File

@ -118,7 +118,7 @@ pub(super) struct SourceToDefCtx<'a, 'b> {
impl SourceToDefCtx<'_, '_> {
pub(super) fn file_to_def(&self, file: FileId) -> SmallVec<[ModuleId; 1]> {
let _p = tracing::span!(tracing::Level::INFO, "SourceBinder::to_module_def");
let _p = tracing::span!(tracing::Level::INFO, "SourceBinder::file_to_module_def");
let mut mods = SmallVec::new();
for &crate_id in self.db.relevant_crates(file).iter() {
// FIXME: inner items

View File

@ -116,7 +116,7 @@ pub(crate) fn new(
) -> Option<Field> {
let db = ctx.sema.db;
let module = ctx.sema.to_module_def(ctx.file_id())?;
let module = ctx.sema.file_to_module_def(ctx.file_id())?;
let (name, range, ty) = match f {
Either::Left(f) => {

View File

@ -25,7 +25,7 @@
// ```
pub(crate) fn move_from_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
let source_file = ctx.find_node_at_offset::<ast::SourceFile>()?;
let module = ctx.sema.to_module_def(ctx.file_id())?;
let module = ctx.sema.file_to_module_def(ctx.file_id())?;
// Enable this assist if the user select all "meaningful" content in the source file
let trimmed_selected_range = trimmed_text_range(&source_file, ctx.selection_trimmed());
let trimmed_file_range = trimmed_text_range(&source_file, source_file.syntax().text_range());

View File

@ -25,7 +25,7 @@
// ```
pub(crate) fn move_to_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
let source_file = ctx.find_node_at_offset::<ast::SourceFile>()?;
let module = ctx.sema.to_module_def(ctx.file_id())?;
let module = ctx.sema.file_to_module_def(ctx.file_id())?;
// Enable this assist if the user select all "meaningful" content in the source file
let trimmed_selected_range = trimmed_text_range(&source_file, ctx.selection_trimmed());
let trimmed_file_range = trimmed_text_range(&source_file, source_file.syntax().text_range());

View File

@ -64,7 +64,7 @@ pub fn visit_file_defs(
cb: &mut dyn FnMut(Definition),
) {
let db = sema.db;
let module = match sema.to_module_def(file_id) {
let module = match sema.file_to_module_def(file_id) {
Some(it) => it,
None => return,
};

View File

@ -200,7 +200,7 @@ fn get_default_constructor(
}
}
let krate = ctx.sema.to_module_def(d.file.original_file(ctx.sema.db))?.krate();
let krate = ctx.sema.file_to_module_def(d.file.original_file(ctx.sema.db))?.krate();
let module = krate.root_module();
// Look for a ::new() associated function

View File

@ -315,7 +315,7 @@ pub fn diagnostics(
handlers::json_is_not_rust::json_in_items(&sema, &mut res, file_id, &node, config);
}
let module = sema.to_module_def(file_id);
let module = sema.file_to_module_def(file_id);
let ctx = DiagnosticsContext { config, sema, resolve };
if module.is_none() {

View File

@ -48,7 +48,7 @@ pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<Na
.flat_map(|module| NavigationTarget::from_module_to_decl(db, module))
.collect(),
None => sema
.to_module_defs(position.file_id)
.file_to_module_defs(position.file_id)
.flat_map(|module| NavigationTarget::from_module_to_decl(db, module))
.collect(),
}

View File

@ -156,7 +156,7 @@ pub(crate) fn will_rename_file(
new_name_stem: &str,
) -> Option<SourceChange> {
let sema = Semantics::new(db);
let module = sema.to_module_def(file_id)?;
let module = sema.file_to_module_def(file_id)?;
let def = Definition::Module(module);
let mut change = if is_raw_identifier(new_name_stem) {
def.rename(&sema, &SmolStr::from_iter(["r#", new_name_stem])).ok()?

View File

@ -178,7 +178,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
}
});
sema.to_module_defs(file_id)
sema.file_to_module_defs(file_id)
.map(|it| runnable_mod_outline_definition(&sema, it))
.for_each(|it| add_opt(it, None));

View File

@ -223,7 +223,7 @@ fn traverse(
krate: hir::Crate,
range_to_highlight: TextRange,
) {
let is_unlinked = sema.to_module_def(file_id).is_none();
let is_unlinked = sema.file_to_module_def(file_id).is_none();
let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default();
enum AttrOrDerive {