cairo_lang_semantic/
semantic.rs

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