pub trait CommonGroup: Database {
// Provided methods
fn find_syntax_node_at_offset<'db>(
&'db self,
file: FileId<'db>,
offset: TextOffset,
) -> Option<SyntaxNode<'db>> { ... }
fn file_and_subfiles_with_corresponding_modules_without_inline<'db>(
&'db self,
file: FileId<'db>,
) -> Option<&'db (OrderedHashSet<FileId<'db>>, OrderedHashSet<ModuleId<'db>>)> { ... }
fn file_and_subfiles_with_corresponding_modules<'db>(
&'db self,
file: FileId<'db>,
) -> Option<&'db (OrderedHashSet<FileId<'db>>, OrderedHashSet<ModuleId<'db>>)> { ... }
fn get_node_resultants<'db>(
&'db self,
node: SyntaxNode<'db>,
) -> Option<&'db Vec<SyntaxNode<'db>>> { ... }
fn find_generated_nodes<'db>(
&'db self,
node_descendant_files: Arc<[FileId<'db>]>,
node: SyntaxNode<'db>,
) -> &'db OrderedHashSet<SyntaxNode<'db>> { ... }
}Provided Methods§
Sourcefn find_syntax_node_at_offset<'db>(
&'db self,
file: FileId<'db>,
offset: TextOffset,
) -> Option<SyntaxNode<'db>>
fn find_syntax_node_at_offset<'db>( &'db self, file: FileId<'db>, offset: TextOffset, ) -> Option<SyntaxNode<'db>>
Finds the most specific SyntaxNode at the given TextOffset in the file.
Sourcefn file_and_subfiles_with_corresponding_modules_without_inline<'db>(
&'db self,
file: FileId<'db>,
) -> Option<&'db (OrderedHashSet<FileId<'db>>, OrderedHashSet<ModuleId<'db>>)>
fn file_and_subfiles_with_corresponding_modules_without_inline<'db>( &'db self, file: FileId<'db>, ) -> Option<&'db (OrderedHashSet<FileId<'db>>, OrderedHashSet<ModuleId<'db>>)>
Collects file and all its descendants together with modules from all these files. Does not includes inline macro expansions.
Sourcefn file_and_subfiles_with_corresponding_modules<'db>(
&'db self,
file: FileId<'db>,
) -> Option<&'db (OrderedHashSet<FileId<'db>>, OrderedHashSet<ModuleId<'db>>)>
fn file_and_subfiles_with_corresponding_modules<'db>( &'db self, file: FileId<'db>, ) -> Option<&'db (OrderedHashSet<FileId<'db>>, OrderedHashSet<ModuleId<'db>>)>
Collects file and all its descendants together with modules from all these files. Includes inline macro expansions.
Sourcefn get_node_resultants<'db>(
&'db self,
node: SyntaxNode<'db>,
) -> Option<&'db Vec<SyntaxNode<'db>>>
fn get_node_resultants<'db>( &'db self, node: SyntaxNode<'db>, ) -> Option<&'db Vec<SyntaxNode<'db>>>
We use the term resultants to refer to generated nodes that are mapped to the original node and are not deleted.
Effectively (user nodes + generated nodes - removed nodes) set always contains resultants for any user defined node.
Semantic data may be available only for resultants.
Consider the following foundry code as an example:
#[test]
#[available_gas(123)]
fn test_fn(){
}This code expands to something like:
#[available_gas(123)]
fn test_fn(){
if is_config_run {
// do config check
return;
}
}It then further transforms to:
fn test_fn(){
if is_config_run {
// do config check
set_available_gas(123);
return;
}
}Let’s label these as files 1, 2 and 3, respectively. The macros used here are attribute proc macros. They delete old code and generate new code.
In this process, test_fn from file 1 is deleted. However, test_fn from file 2 is mapped to it.
Therefore, we should ignore test_fn from file 1 as it no longer exists and
should use test_fn from file 2. But then, test_fn from file 2 is effectively replaced by test_fn from file 3, so test_fn from file 2 is now deleted.
In this scenario, only test_fn from file 3 is a resultant. Both test_fn from files 1 and 2 were deleted.
So for input being test_fn from file 1, only test_fn from file 3 is returned
Now, consider another example:
The generate_trait macro is a builtin macro that does not remove the original code. Thus, we have the following code:
#[generate_trait]
impl FooImpl for FooTrait {}This code generates the following:
trait FooTrait {}Both the original and the generated files are considered when calculating semantics, since original FooTrait was not removed.
Additionally FooTrait from file 2 is mapped to FooTrait from file 1.
Therefore for FooTrait from file 1, FooTrait from file 1 and FooTrait from file 2 are returned.