Skip to content

Commit 256b4fa

Browse files
authored
Move find module containing node to semantic (#8783)
1 parent 88c2d2c commit 256b4fa

File tree

4 files changed

+56
-58
lines changed

4 files changed

+56
-58
lines changed

crates/cairo-lang-defs/src/db.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,7 +1873,7 @@ pub trait DefsGroupEx: DefsGroup {
18731873
///
18741874
/// *Note*: Sets the following Salsa input: `DefsGroup::macro_plugin_overrides`.
18751875
fn set_override_crate_macro_plugins<'db>(
1876-
&mut self,
1876+
&'db mut self,
18771877
crate_id: CrateId<'db>,
18781878
plugins: Arc<Vec<MacroPluginId<'db>>>,
18791879
) {
@@ -1890,7 +1890,7 @@ pub trait DefsGroupEx: DefsGroup {
18901890
///
18911891
/// *Note*: Sets the following Salsa input: `DefsGroup::inline_macro_plugin_overrides`.
18921892
fn set_override_crate_inline_macro_plugins<'db>(
1893-
&mut self,
1893+
&'db mut self,
18941894
crate_id: CrateId<'db>,
18951895
plugins: Arc<OrderedHashMap<String, InlineMacroExprPluginId<'db>>>,
18961896
) {

crates/cairo-lang-doc/src/parser.rs

Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::fmt;
22

33
use cairo_lang_debug::DebugWithDb;
4-
use cairo_lang_defs::db::DefsGroup;
54
use cairo_lang_defs::ids::{GenericTypeId, LookupItemId, ModuleId, ModuleItemId, TraitItemId};
65
use cairo_lang_diagnostics::DiagnosticsBuilder;
76
use cairo_lang_filesystem::db::FilesGroup;
@@ -10,11 +9,9 @@ use cairo_lang_parser::parser::Parser;
109
use cairo_lang_semantic::diagnostic::{NotFoundItemType, SemanticDiagnostics};
1110
use cairo_lang_semantic::expr::inference::InferenceId;
1211
use cairo_lang_semantic::items::functions::GenericFunctionId;
13-
use cairo_lang_semantic::items::module::ModuleSemantic;
12+
use cairo_lang_semantic::lsp_helpers::LspHelpers;
1413
use cairo_lang_semantic::resolve::{AsSegments, ResolutionContext, ResolvedGenericItem, Resolver};
15-
use cairo_lang_syntax::node::ast::{Expr, ExprPath, ItemModule};
16-
use cairo_lang_syntax::node::helpers::GetIdentifier;
17-
use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode};
14+
use cairo_lang_syntax::node::ast::{Expr, ExprPath};
1815
use cairo_lang_utils::Intern;
1916
use itertools::Itertools;
2017
use pulldown_cmark::{
@@ -336,7 +333,7 @@ impl<'db> DocumentationCommentParser<'db> {
336333
path: String,
337334
) -> Option<DocumentableItemId<'db>> {
338335
let syntax_node = item_id.stable_location(self.db)?.syntax_node(self.db);
339-
let containing_module = self.find_module_containing_node(&syntax_node)?;
336+
let containing_module = self.db.find_module_containing_node(syntax_node)?;
340337
let mut resolver = Resolver::new(self.db, containing_module, InferenceId::NoContext);
341338
let mut diagnostics = SemanticDiagnostics::default();
342339
let segments = self.parse_comment_link_path(path)?;
@@ -373,55 +370,6 @@ impl<'db> DocumentationCommentParser<'db> {
373370

374371
if let Expr::Path(expr_path) = expr { Some(expr_path) } else { None }
375372
}
376-
377-
/// Finds a [`ModuleId`] containing the node.
378-
///
379-
/// If the node is located in a virtual file generated by a compiler plugin, this method will
380-
/// return the (sub)module of the main, user-written file that leads to the node.
381-
fn find_module_containing_node(&self, node: &SyntaxNode<'db>) -> Option<ModuleId<'db>> {
382-
let db = self.db;
383-
384-
// Get the main module of the main file that leads to the node.
385-
// The node may be located in a virtual file of a submodule.
386-
// This code attempts to get the absolute "parent" of both "module" and "file" parts.
387-
let main_module = {
388-
// Get the file where the node is located.
389-
// This might be a virtual file generated by a compiler plugin.
390-
let node_file_id = node.stable_ptr(db).file_id(db);
391-
392-
// Get the root module of a file containing the node.
393-
let node_main_module = db.file_modules(node_file_id).ok()?.iter().copied().next()?;
394-
395-
// Get the main module of the file.
396-
let main_file = db.module_main_file(node_main_module).ok()?;
397-
398-
// Get the main module of that file.
399-
db.file_modules(main_file).ok()?.iter().copied().next()?
400-
};
401-
402-
// Get the stack (bottom-up) of submodule names in the file containing the node, in the main
403-
// module, that lead to the node.
404-
node.ancestors(db)
405-
.filter_map(|node| ItemModule::cast(db, node))
406-
.map(|item_module| {
407-
item_module
408-
.stable_ptr(db)
409-
.name_green(db)
410-
.identifier(db)
411-
})
412-
// Buffer the stack to get DoubleEndedIterator.
413-
.collect::<Vec<_>>()
414-
.into_iter()
415-
// And get id of the (sub)module containing the node by traversing this stack top-down.
416-
.try_rfold(main_module, |module, name| {
417-
let ModuleItemId::Submodule(submodule) =
418-
db.module_item_by_name(module, name).ok()??
419-
else {
420-
return None;
421-
};
422-
Some(ModuleId::Submodule(submodule))
423-
})
424-
}
425373
}
426374

427375
trait ToDocumentableItemId<'db, T> {

crates/cairo-lang-semantic/src/db.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ pub trait SemanticGroupEx: Database {
528528
semantic_group_input(db_ref).set_analyzer_plugin_overrides(self).to(Some(overrides));
529529
}
530530
}
531+
531532
impl<T: Database + ?Sized> SemanticGroupEx for T {}
532533

533534
/// An extension trait for [`SemanticGroup`] to manage plugin setters.

crates/cairo-lang-semantic/src/lsp_helpers.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ use std::sync::Arc;
22

33
use cairo_lang_defs::db::DefsGroup;
44
use cairo_lang_defs::ids::{
5-
GenericTypeId, ImportableId, LanguageElementId, ModuleId, NamedLanguageElementId,
5+
GenericTypeId, ImportableId, LanguageElementId, ModuleId, ModuleItemId, NamedLanguageElementId,
66
TraitFunctionId, TraitId,
77
};
88
use cairo_lang_filesystem::db::{CORELIB_CRATE_NAME, FilesGroup, default_crate_settings};
99
use cairo_lang_filesystem::ids::{CrateId, CrateLongId, FileId, SmolStrId, Tracked};
10+
use cairo_lang_syntax::node::ast::ItemModule;
11+
use cairo_lang_syntax::node::helpers::GetIdentifier;
12+
use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode};
1013
use cairo_lang_utils::Intern;
1114
use cairo_lang_utils::ordered_hash_map::{Entry, OrderedHashMap};
1215
use cairo_lang_utils::unordered_hash_set::UnorderedHashSet;
@@ -550,6 +553,47 @@ fn inline_macro_expansion_files_tracked<'db>(
550553
files
551554
}
552555

556+
#[salsa::tracked]
557+
fn find_module_containing_node<'db>(
558+
db: &'db dyn Database,
559+
_tracked: Tracked,
560+
node: SyntaxNode<'db>,
561+
) -> Option<ModuleId<'db>> {
562+
// Get the main module of the main file containing the node.
563+
// The node may be located in a virtual file of a submodule.
564+
let main_module = {
565+
// Get the file where the node is located.
566+
// This might be a virtual file generated by a compiler plugin.
567+
let node_file_id = node.stable_ptr(db).file_id(db);
568+
569+
// Get the root module of a file containing the node.
570+
*db.file_modules(node_file_id).ok()?.first()?
571+
};
572+
573+
// Get the stack (bottom-up) of submodule names in the file containing the node, in the main
574+
// module, that lead to the node.
575+
node.ancestors(db)
576+
.filter_map(|node| ItemModule::cast(db, node))
577+
.map(|item_module| {
578+
item_module
579+
.stable_ptr(db)
580+
.name_green(db)
581+
.identifier(db)
582+
})
583+
// Buffer the stack to get DoubleEndedIterator.
584+
.collect::<Vec<_>>()
585+
.into_iter()
586+
// And get id of the (sub)module containing the node by traversing this stack top-down.
587+
.try_rfold(main_module, |module, name| {
588+
let ModuleItemId::Submodule(submodule) =
589+
db.module_item_by_name(module, name).ok()??
590+
else {
591+
return None;
592+
};
593+
Some(ModuleId::Submodule(submodule))
594+
})
595+
}
596+
553597
/// Trait for LSP helpers.
554598
pub trait LspHelpers<'db>: Database {
555599
/// Returns all methods in a module that match the given type filter.
@@ -612,5 +656,10 @@ pub trait LspHelpers<'db>: Database {
612656
fn inline_macro_expansion_files(&'db self, module_id: ModuleId<'db>) -> &'db Vec<FileId<'db>> {
613657
inline_macro_expansion_files_tracked(self.as_dyn_database(), (), module_id)
614658
}
659+
660+
/// Finds a [`ModuleId`] containing the node.
661+
fn find_module_containing_node(&'db self, node: SyntaxNode<'db>) -> Option<ModuleId<'db>> {
662+
find_module_containing_node(self.as_dyn_database(), (), node)
663+
}
615664
}
616665
impl<'db, T: Database + ?Sized> LspHelpers<'db> for T {}

0 commit comments

Comments
 (0)