cairo_lang_semantic/items/
attribute.rs1use cairo_lang_defs::ids::{
2 EnumId, ExternTypeId, FreeFunctionId, FunctionWithBodyId, ImplAliasId, ImplDefId,
3 ImplFunctionId, ImplTypeDefId, ModuleId, StructId, SubmoduleId, TraitFunctionId, TraitId,
4 TraitTypeId,
5};
6use cairo_lang_diagnostics::Maybe;
7use cairo_lang_syntax::attribute::structured::Attribute;
8
9use crate::db::SemanticGroup;
10use crate::{ConcreteEnumId, ConcreteExternTypeId, ConcreteStructId};
11
12pub trait AttributeTrait {
13 fn name(&self, db: &dyn SemanticGroup) -> String;
14 fn args(&self, db: &dyn SemanticGroup) -> String;
15 fn full_text(&self, db: &dyn SemanticGroup) -> String {
16 if self.args(db).is_empty() {
17 self.name(db)
18 } else {
19 format!("{}({})", self.name(db), self.args(db))
20 }
21 }
22 fn format(&self, db: &dyn SemanticGroup) -> String {
23 format!("#[{}]", self.full_text(db))
24 }
25}
26impl AttributeTrait for Attribute {
27 fn name(&self, _db: &dyn SemanticGroup) -> String {
28 self.id.to_string()
29 }
30 fn args(&self, db: &dyn SemanticGroup) -> String {
31 self.args.iter().map(|arg| arg.text(db.upcast())).collect::<Vec<_>>().join(", ")
32 }
33}
34
35pub trait SemanticQueryAttrs {
37 #[doc(hidden)]
41 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>>;
42
43 fn query_attr(&self, db: &dyn SemanticGroup, attr: &str) -> Maybe<Vec<Attribute>> {
45 Ok(self.attributes_elements(db)?.into_iter().filter(|a| a.name(db) == attr).collect())
46 }
47
48 fn find_attr(&self, db: &dyn SemanticGroup, attr: &str) -> Maybe<Option<Attribute>> {
50 Ok(self.query_attr(db, attr)?.into_iter().next())
51 }
52
53 fn has_attr(&self, db: &dyn SemanticGroup, attr: &str) -> Maybe<bool> {
55 Ok(self.find_attr(db, attr)?.is_some())
56 }
57
58 fn has_attr_with_arg(
60 &self,
61 db: &dyn SemanticGroup,
62 attr_name: &str,
63 arg_name: &str,
64 ) -> Maybe<bool> {
65 Ok(self
66 .query_attr(db, attr_name)?
67 .iter()
68 .any(|attr| attr.is_single_unnamed_arg(db.upcast(), arg_name)))
69 }
70}
71
72impl SemanticQueryAttrs for ModuleId {
73 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
74 db.module_attributes(*self)
75 }
76}
77impl SemanticQueryAttrs for StructId {
78 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
79 db.struct_attributes(*self)
80 }
81}
82impl SemanticQueryAttrs for ConcreteStructId {
83 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
84 self.struct_id(db).attributes_elements(db)
85 }
86}
87impl SemanticQueryAttrs for TraitId {
88 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
89 db.trait_attributes(*self)
90 }
91}
92impl SemanticQueryAttrs for FunctionWithBodyId {
93 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
94 db.function_with_body_attributes(*self)
95 }
96}
97impl SemanticQueryAttrs for ImplDefId {
98 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
99 db.impl_def_attributes(*self)
100 }
101}
102impl SemanticQueryAttrs for ImplAliasId {
103 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
104 db.impl_alias_attributes(*self)
105 }
106}
107impl SemanticQueryAttrs for EnumId {
108 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
109 db.enum_attributes(*self)
110 }
111}
112impl SemanticQueryAttrs for ConcreteEnumId {
113 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
114 self.enum_id(db).attributes_elements(db)
115 }
116}
117impl SemanticQueryAttrs for ExternTypeId {
118 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
119 db.extern_type_attributes(*self)
120 }
121}
122impl SemanticQueryAttrs for ConcreteExternTypeId {
123 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
124 self.extern_type_id(db).attributes_elements(db)
125 }
126}
127impl SemanticQueryAttrs for SubmoduleId {
128 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
129 ModuleId::Submodule(*self).attributes_elements(db)
130 }
131}
132impl SemanticQueryAttrs for FreeFunctionId {
133 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
134 FunctionWithBodyId::Free(*self).attributes_elements(db)
135 }
136}
137
138impl SemanticQueryAttrs for TraitTypeId {
139 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
140 db.trait_type_attributes(*self)
141 }
142}
143impl SemanticQueryAttrs for TraitFunctionId {
144 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
145 db.trait_function_attributes(*self)
146 }
147}
148
149impl SemanticQueryAttrs for ImplTypeDefId {
150 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
151 db.impl_type_def_attributes(*self)
152 }
153}
154impl SemanticQueryAttrs for ImplFunctionId {
155 fn attributes_elements(&self, db: &dyn SemanticGroup) -> Maybe<Vec<Attribute>> {
156 db.impl_function_attributes(*self)
157 }
158}