1use cairo_lang_defs::ids::{LocalVarId, StatementItemId};
2pub use cairo_lang_defs::ids::{ParamId, VarId};
4use cairo_lang_filesystem::ids::SmolStrId;
5use cairo_lang_proc_macros::{DebugWithDb, SemanticObject};
6use cairo_lang_syntax::node::ids::SyntaxStablePtrId;
7use cairo_lang_syntax::node::{TypedStablePtr, ast};
8use salsa::Database;
9
10pub use super::expr::objects::*;
11pub use crate::expr::pattern::{
12    Pattern, PatternEnumVariant, PatternFixedSizeArray, PatternLiteral, PatternOtherwise,
13    PatternStringLiteral, PatternStruct, PatternTuple, PatternVariable,
14};
15use crate::items::constant::ConstValueId;
16pub use crate::items::enm::{ConcreteVariant, MatchArmSelector, ValueSelectorArm, Variant};
17pub use crate::items::function_with_body::FunctionBody;
18pub use crate::items::functions::{
19    ConcreteFunction, ConcreteFunctionWithBodyId, FunctionId, FunctionLongId, Signature,
20};
21pub use crate::items::generics::{GenericArgumentId, GenericParam};
22pub use crate::items::imp::{ConcreteImplId, ConcreteImplLongId};
23pub use crate::items::structure::Member;
24pub use crate::items::trt::{ConcreteTraitId, ConcreteTraitLongId};
25pub use crate::types::{
26    ConcreteEnumId, ConcreteExternTypeId, ConcreteStructId, ConcreteTypeId, TypeId, TypeLongId,
27};
28
29#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
31#[debug_db(dyn Database)]
32pub struct LocalVariable<'db> {
33    pub id: LocalVarId<'db>,
34    pub ty: TypeId<'db>,
35    #[dont_rewrite]
36    pub is_mut: bool,
37    #[dont_rewrite]
38    pub allow_unused: bool,
39}
40impl<'db> LocalVariable<'db> {
41    pub fn stable_ptr(&self, db: &'db dyn Database) -> ast::TerminalIdentifierPtr<'db> {
42        self.id.stable_ptr(db)
43    }
44}
45
46#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
48#[debug_db(dyn Database)]
49pub struct LocalItem<'db> {
50    pub id: StatementItemId<'db>,
51    pub kind: StatementItemKind<'db>,
52}
53
54#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
56#[debug_db(dyn Database)]
57pub enum StatementItemKind<'db> {
58    Constant(ConstValueId<'db>, TypeId<'db>),
59}
60
61#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, SemanticObject, salsa::Update)]
62#[debug_db(dyn Database)]
63pub struct Parameter<'db> {
64    pub id: ParamId<'db>,
65    #[dont_rewrite]
66    pub name: SmolStrId<'db>,
67    pub ty: TypeId<'db>,
68    #[dont_rewrite]
69    pub mutability: Mutability,
70    #[hide_field_debug_with_db]
71    #[dont_rewrite]
72    pub stable_ptr: ast::TerminalIdentifierPtr<'db>,
73}
74impl<'db> Parameter<'db> {
75    pub fn stable_ptr(&self, db: &'db dyn Database) -> ast::ParamPtr<'db> {
76        self.id.stable_ptr(db)
77    }
78}
79
80#[derive(Debug, Clone, Hash, PartialEq, Eq, Copy, salsa::Update)]
82pub enum Mutability {
83    Immutable,
85    Mutable,
87    Reference,
90}
91
92#[derive(Clone, Debug, Hash, PartialEq, Eq, DebugWithDb, salsa::Update)]
93#[debug_db(dyn Database)]
94pub enum Binding<'db> {
95    LocalVar(LocalVariable<'db>),
96    Param(Parameter<'db>),
97    LocalItem(LocalItem<'db>),
98}
99impl<'db> Binding<'db> {
100    pub fn id(&self) -> VarId<'db> {
101        match self {
102            Binding::LocalVar(local) => VarId::Local(local.id),
103            Binding::Param(param) => VarId::Param(param.id),
104            Binding::LocalItem(local) => VarId::Item(local.id),
105        }
106    }
107    pub fn ty(&self) -> TypeId<'db> {
108        match self {
109            Binding::LocalVar(local) => local.ty,
110            Binding::Param(param) => param.ty,
111            Binding::LocalItem(local) => match local.kind {
112                StatementItemKind::Constant(_, ty) => ty,
113            },
114        }
115    }
116    pub fn is_mut(&self) -> bool {
117        match self {
118            Binding::LocalVar(local) => local.is_mut,
119            Binding::Param(param) => param.mutability != Mutability::Immutable,
120            Binding::LocalItem(_) => false,
121        }
122    }
123    pub fn stable_ptr(&self, db: &'db dyn Database) -> SyntaxStablePtrId<'db> {
124        match self {
125            Binding::LocalVar(local) => local.stable_ptr(db).untyped(),
126            Binding::Param(param) => param.stable_ptr(db).untyped(),
127            Binding::LocalItem(local) => local.id.name_stable_ptr(db),
128        }
129    }
130}
131impl<'db> From<LocalVariable<'db>> for Binding<'db> {
132    fn from(var: LocalVariable<'db>) -> Self {
133        Self::LocalVar(var)
134    }
135}
136impl<'db> From<Parameter<'db>> for Binding<'db> {
137    fn from(param: Parameter<'db>) -> Self {
138        Self::Param(param)
139    }
140}