use cairo_lang_defs::ids::{ImportableId, VarId};
use cairo_lang_semantic::{Binding, Mutability};
use cairo_lang_syntax::node::db::SyntaxGroup;
use cairo_lang_syntax::node::ids::SyntaxStablePtrId;
use cairo_lang_syntax::node::{SyntaxNode, Terminal, TypedStablePtr, TypedSyntaxNode, ast};
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
use crate::ide::format::types::format_type;
use crate::lang::db::{AnalysisDatabase, LsSemanticGroup};
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct VariableDef<'db> {
var_id: VarId<'db>,
identifier: ast::TerminalIdentifier<'db>,
}
impl<'db> VariableDef<'db> {
pub(super) fn new(
db: &'db AnalysisDatabase,
var_id: VarId<'db>,
definition_node: SyntaxNode<'db>,
) -> Self {
let identifier = ast::TerminalIdentifier::from_syntax_node(db, definition_node);
Self { var_id, identifier }
}
pub fn definition_node(&self) -> SyntaxNode<'db> {
self.identifier.as_syntax_node()
}
pub fn definition_stable_ptr(&self, db: &'db dyn SyntaxGroup) -> SyntaxStablePtrId<'db> {
self.identifier.stable_ptr(db).untyped()
}
pub fn signature(
&self,
db: &'db AnalysisDatabase,
importables: &OrderedHashMap<ImportableId<'db>, String>,
) -> Option<String> {
let name = self.name(db);
let binding = db.lookup_binding(self.var_id)?;
let prefix = match &binding {
Binding::LocalVar(_) => "let ",
Binding::LocalItem(_) => "const ",
Binding::Param(_) => "",
};
let mutability = match &binding {
Binding::LocalVar(local) => {
if local.is_mut {
"mut "
} else {
""
}
}
Binding::LocalItem(_) => "",
Binding::Param(param) => match param.mutability {
Mutability::Immutable => "",
Mutability::Mutable => "mut ",
Mutability::Reference => "ref ",
},
};
let type_id = binding.ty();
let ty = format_type(db, type_id, importables, None);
Some(format!("{prefix}{mutability}{name}: {ty}"))
}
pub fn name(&self, db: &'db AnalysisDatabase) -> String {
self.identifier.text(db).to_string(db)
}
}