Skip to content

Commit

Permalink
Added hover for path segments
Browse files Browse the repository at this point in the history
  • Loading branch information
integraledelebesgue committed Nov 15, 2024
1 parent 4a674b5 commit 55e018f
Show file tree
Hide file tree
Showing 5 changed files with 421 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ pub fn definition(
md
}

SymbolDef::Module(module) => {
let mut md = String::new();
md += &fenced_code_block(&module.definition_path());
md += &fenced_code_block(&module.signature());
if let Some(doc) = module.documentation(db) {
md += RULE;
md += &doc;
}
md
}

SymbolDef::Variable(var) => fenced_code_block(&var.signature(db)),
SymbolDef::ExprInlineMacro(macro_name) => {
let mut md = fenced_code_block(macro_name);
Expand Down
60 changes: 58 additions & 2 deletions crates/cairo-lang-language-server/src/lang/inspect/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use cairo_lang_defs::ids::{
};
use cairo_lang_diagnostics::ToOption;
use cairo_lang_doc::db::DocGroup;
use cairo_lang_doc::documentable_item::DocumentableItemId;
use cairo_lang_parser::db::ParserGroup;
use cairo_lang_semantic::db::SemanticGroup;
use cairo_lang_semantic::expr::pattern::QueryPatternVariablesFromDb;
Expand Down Expand Up @@ -38,6 +39,7 @@ pub enum SymbolDef {
Variable(VariableDef),
ExprInlineMacro(String),
Member(MemberDef),
Module(ModuleDef),
}

/// Information about a struct member.
Expand Down Expand Up @@ -78,7 +80,6 @@ impl SymbolDef {

match definition_item {
ResolvedItem::Generic(ResolvedGenericItem::GenericConstant(_))
| ResolvedItem::Generic(ResolvedGenericItem::Module(_))
| ResolvedItem::Generic(ResolvedGenericItem::GenericFunction(_))
| ResolvedItem::Generic(ResolvedGenericItem::TraitFunction(_))
| ResolvedItem::Generic(ResolvedGenericItem::GenericType(_))
Expand All @@ -88,7 +89,6 @@ impl SymbolDef {
| ResolvedItem::Generic(ResolvedGenericItem::Trait(_))
| ResolvedItem::Generic(ResolvedGenericItem::Impl(_))
| ResolvedItem::Concrete(ResolvedConcreteItem::Constant(_))
| ResolvedItem::Concrete(ResolvedConcreteItem::Module(_))
| ResolvedItem::Concrete(ResolvedConcreteItem::Function(_))
| ResolvedItem::Concrete(ResolvedConcreteItem::TraitFunction(_))
| ResolvedItem::Concrete(ResolvedConcreteItem::Type(_))
Expand All @@ -98,6 +98,14 @@ impl SymbolDef {
ItemDef::new(db, &definition_node).map(Self::Item)
}

ResolvedItem::Generic(ResolvedGenericItem::Module(id)) => {
Some(Self::Module(ModuleDef::new(db, id)))
}

ResolvedItem::Concrete(ResolvedConcreteItem::Module(id)) => {
Some(Self::Module(ModuleDef::new(db, id)))
}

ResolvedItem::Generic(ResolvedGenericItem::Variable(_)) => {
VariableDef::new(db, definition_node).map(Self::Variable)
}
Expand Down Expand Up @@ -290,6 +298,54 @@ impl VariableDef {
}
}

/// Information about the definition of a module.
pub struct ModuleDef {
id: ModuleId,
name: SmolStr,
/// A full path to the parent module if [`ModuleId`] points to a submodule,
/// None otherwise (i.e. for a crate root).
parent_full_path: Option<String>,
}

impl ModuleDef {
/// Constructs new [`ModuleDef`] instance.
pub fn new(db: &AnalysisDatabase, id: ModuleId) -> Self {
let name = id.name(db);
let parent_full_path = id
.full_path(db)
.strip_suffix(name.as_str())
.unwrap()
.strip_suffix("::") // Fails when path lacks `::`, i.e. when we import from a crate root.
.map(String::from);

ModuleDef { id, name, parent_full_path }
}

/// Gets the module signature: a name preceeded by a qualifier: "mod" for submodule

Check warning on line 324 in crates/cairo-lang-language-server/src/lang/inspect/defs.rs

View workflow job for this annotation

GitHub Actions / typos

"preceeded" should be "preceded" or "proceeded".
/// and "crate" for crate root.
pub fn signature(&self) -> String {
let prefix = if self.parent_full_path.is_some() { "mod" } else { "crate" };
format!("{prefix} {}", self.name)
}

/// Gets the full path of a parent module of the current module.
pub fn definition_path(&self) -> String {
self.parent_full_path.clone().unwrap_or_default()
}

/// Gets the module's documentation if it's available.
pub fn documentation(&self, db: &AnalysisDatabase) -> Option<String> {
let doc_id = match self.id {
ModuleId::CrateRoot(id) => DocumentableItemId::Crate(id),
ModuleId::Submodule(id) => DocumentableItemId::LookupItem(LookupItemId::ModuleItem(
ModuleItemId::Submodule(id),
)),
};

db.get_item_documentation(doc_id)
}
}

// TODO(mkaput): make private.
pub fn find_definition(
db: &AnalysisDatabase,
Expand Down
1 change: 1 addition & 0 deletions crates/cairo-lang-language-server/tests/e2e/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ cairo_lang_test_utils::test_file_test!(
partial: "partial.txt",
starknet: "starknet.txt",
literals: "literals.txt",
paths: "paths.txt",
},
test_hover
);
Expand Down
14 changes: 10 additions & 4 deletions crates/cairo-lang-language-server/tests/test_data/hover/basic.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,20 +170,26 @@ fn add_two(x: u32) -> u32
// = source context
front<caret>_of_house::hosting::add_to_waitlist();
// = highlight
No highlight information.
<sel>front_of_house</sel>::hosting::add_to_waitlist();
// = popover
```cairo
fn add_to_waitlist() -> ()
hello
```
```cairo
mod front_of_house
```

//! > hover #7
// = source context
front_of_house::ho<caret>sting::add_to_waitlist();
// = highlight
No highlight information.
front_of_house::<sel>hosting</sel>::add_to_waitlist();
// = popover
```cairo
fn add_to_waitlist() -> ()
hello::front_of_house
```
```cairo
mod hosting
```

//! > hover #8
Expand Down
Loading

0 comments on commit 55e018f

Please sign in to comment.