Skip to content

Commit

Permalink
Find definition for enum variant declarations
Browse files Browse the repository at this point in the history
commit-id:c9a15717
  • Loading branch information
mkaput committed Feb 5, 2025
1 parent 3cd27f5 commit 6dd5b25
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
28 changes: 26 additions & 2 deletions src/lang/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::iter;

use cairo_lang_defs::db::DefsGroup;
use cairo_lang_defs::ids::{
GenericTypeId, LanguageElementId, LocalVarLongId, LookupItemId, MemberId, ModuleId,
EnumLongId, GenericTypeId, LanguageElementId, LocalVarLongId, LookupItemId, MemberId, ModuleId,
ModuleItemId, NamedLanguageElementId, StructLongId, SubmoduleLongId, TopLevelLanguageElementId,
TraitItemId, VarId,
};
Expand All @@ -20,7 +20,7 @@ use cairo_lang_semantic::items::generics::generic_params_to_args;
use cairo_lang_semantic::items::imp::ImplLongId;
use cairo_lang_semantic::lookup_item::LookupItemEx;
use cairo_lang_semantic::resolve::{ResolvedConcreteItem, ResolvedGenericItem};
use cairo_lang_semantic::{Binding, ConcreteTraitLongId, Expr, Mutability, TypeLongId};
use cairo_lang_semantic::{Binding, ConcreteTraitLongId, Expr, Mutability, TypeLongId, Variant};
use cairo_lang_syntax::node::ids::SyntaxStablePtrId;
use cairo_lang_syntax::node::kind::SyntaxKind;
use cairo_lang_syntax::node::{SyntaxNode, Terminal, TypedStablePtr, TypedSyntaxNode, ast};
Expand Down Expand Up @@ -453,6 +453,11 @@ fn find_definition(
));
}

if let Some(variant) = try_extract_variant_declaration(db, identifier) {
let item = ResolvedGenericItem::Variant(variant);
return Some((ResolvedItem::Generic(item.clone()), resolved_generic_item_def(db, item)?));
}

if let Some(var_id) = try_extract_variable_declaration(db, identifier, lookup_items) {
let item = ResolvedGenericItem::Variable(var_id);
return Some((ResolvedItem::Generic(item.clone()), resolved_generic_item_def(db, item)?));
Expand Down Expand Up @@ -594,6 +599,25 @@ fn try_extract_member_declaration(
Some(member_semantic.id)
}

/// Extracts [`VariantId`] if the [`TerminalIdentifier`] is a name of variant in enum declaration.
fn try_extract_variant_declaration(
db: &AnalysisDatabase,
identifier: &ast::TerminalIdentifier,
) -> Option<Variant> {
let variant = identifier.as_syntax_node().parent_of_type::<ast::Variant>(db)?;
assert_eq!(variant.name(db), *identifier);
let item_enum = variant.as_syntax_node().parent_of_type::<ast::ItemEnum>(db)?;
let enum_id = EnumLongId(
db.find_module_file_containing_node(&item_enum.as_syntax_node())?,
item_enum.stable_ptr(),
)
.intern(db);
let enum_variants = db.enum_variants(enum_id).ok()?;
let variant_id = *enum_variants.get(&variant.name(db).text(db))?;
let variant = db.variant_semantic(enum_id, variant_id).ok()?;
Some(variant)
}

/// Lookups if the identifier is a declaration of a variable/param in one of the lookup items.
///
/// Declaration identifiers aren't kept in `ResolvedData`, which is searched for by
Expand Down
26 changes: 24 additions & 2 deletions tests/e2e/goto_definition/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,36 @@ fn enum_item_in_expr() {
");
}

#[test]
fn enum_item_in_declaration() {
test_transform!(goto_definition, r#"
enum Fo<caret>o { Bar }
fn main() { let _foo = Foo::Bar; }
"#, @r"
enum <sel>Foo</sel> { Bar }
fn main() { let _foo = Foo::Bar; }
");
}

#[test]
fn enum_variant_in_declaration() {
test_transform!(goto_definition, r#"
enum Foo { Ba<caret>r: felt252 }
fn main() { let _foo = Foo::Bar(0); }
"#, @r"
enum Foo { <sel>Bar</sel>: felt252 }
fn main() { let _foo = Foo::Bar(0); }
");
}

#[test]
fn enum_variant_in_expr() {
test_transform!(goto_definition, r#"
enum Foo { Bar: felt252 }
fn main() { let foo = Foo::Ba<caret>r; }
fn main() { let foo = Foo::Ba<caret>r(0); }
"#, @r"
enum Foo { <sel>Bar</sel>: felt252 }
fn main() { let foo = Foo::Bar; }
fn main() { let foo = Foo::Bar(0); }
");
}

Expand Down

0 comments on commit 6dd5b25

Please sign in to comment.