edb_engine/analysis/
function.rs1use std::sync::Arc;
18
19use foundry_compilers::artifacts::{
20 ast::SourceLocation, FunctionDefinition, FunctionTypeName, ModifierDefinition, StateMutability,
21 Visibility,
22};
23use once_cell::sync::OnceCell;
24use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
25use serde::{Deserialize, Serialize};
26
27use crate::analysis::{macros::universal_id, ContractRef, StepRef};
28
29universal_id! {
30 UFID => 0
32}
33
34#[derive(Debug, Clone)]
40pub struct FunctionRef {
41 inner: Arc<RwLock<Function>>,
42 ufid: OnceCell<UFID>,
44 contract: OnceCell<Option<ContractRef>>,
45}
46
47impl From<Function> for FunctionRef {
48 fn from(function: Function) -> Self {
49 Self::new(function)
50 }
51}
52
53impl FunctionRef {
54 pub fn new(inner: Function) -> Self {
56 Self {
57 inner: Arc::new(RwLock::new(inner)),
58 ufid: OnceCell::new(),
59 contract: OnceCell::new(),
60 }
61 }
62}
63
64impl FunctionRef {
65 pub(crate) fn read(&self) -> RwLockReadGuard<'_, Function> {
66 self.inner.read()
67 }
68
69 pub(crate) fn write(&self) -> RwLockWriteGuard<'_, Function> {
70 self.inner.write()
71 }
72}
73
74impl FunctionRef {
75 pub fn ufid(&self) -> UFID {
77 *self.ufid.get_or_init(|| self.inner.read().ufid)
78 }
79
80 pub fn contract(&self) -> Option<ContractRef> {
82 self.contract.get_or_init(|| self.inner.read().contract.clone()).clone()
83 }
84
85 pub fn name(&self) -> String {
87 self.read().definition.name().to_string()
88 }
89
90 pub fn visibility(&self) -> Visibility {
92 self.read().definition.visibility().clone()
93 }
94
95 pub fn state_mutability(&self) -> Option<StateMutability> {
97 self.read().definition.state_mutability().cloned()
98 }
99
100 pub fn src(&self) -> SourceLocation {
102 *self.read().definition.src()
103 }
104}
105
106impl Serialize for FunctionRef {
107 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
108 where
109 S: serde::Serializer,
110 {
111 self.inner.read().serialize(serializer)
112 }
113}
114
115impl<'de> Deserialize<'de> for FunctionRef {
116 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
117 where
118 D: serde::Deserializer<'de>,
119 {
120 let function = Function::deserialize(deserializer)?;
121 Ok(Self::new(function))
122 }
123}
124
125#[derive(Debug, Clone)]
131pub struct FunctionTypeNameRef {
132 inner: Arc<RwLock<FunctionTypeName>>,
133}
134
135impl From<FunctionTypeName> for FunctionTypeNameRef {
136 fn from(function_type: FunctionTypeName) -> Self {
137 Self::new(function_type)
138 }
139}
140
141impl FunctionTypeNameRef {
142 pub fn new(inner: FunctionTypeName) -> Self {
144 Self { inner: Arc::new(RwLock::new(inner)) }
145 }
146}
147
148#[allow(unused)]
149impl FunctionTypeNameRef {
150 pub(crate) fn read(&self) -> RwLockReadGuard<'_, FunctionTypeName> {
151 self.inner.read()
152 }
153
154 pub(crate) fn write(&self) -> RwLockWriteGuard<'_, FunctionTypeName> {
155 self.inner.write()
156 }
157}
158
159impl FunctionTypeNameRef {
160 pub fn visibility(&self) -> Visibility {
162 self.read().visibility.clone()
163 }
164
165 pub fn state_mutability(&self) -> StateMutability {
167 self.read().state_mutability.clone()
168 }
169
170 pub fn src(&self) -> SourceLocation {
172 self.read().src
173 }
174}
175
176impl Serialize for FunctionTypeNameRef {
177 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
178 where
179 S: serde::Serializer,
180 {
181 self.inner.read().serialize(serializer)
182 }
183}
184
185impl<'de> Deserialize<'de> for FunctionTypeNameRef {
186 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
187 where
188 D: serde::Deserializer<'de>,
189 {
190 let function_type = FunctionTypeName::deserialize(deserializer)?;
191 Ok(Self::new(function_type))
192 }
193}
194
195#[derive(Debug, Clone, Serialize, Deserialize)]
197pub struct Function {
198 pub ufid: UFID,
200 pub contract: Option<ContractRef>,
202 pub definition: FunctionVariant,
204 pub steps: Vec<StepRef>,
206}
207
208#[derive(Debug, Clone, Serialize, Deserialize, derive_more::From)]
210pub enum FunctionVariant {
211 Function(#[from] FunctionDefinition),
213 Modifier(#[from] ModifierDefinition),
215}
216
217impl FunctionVariant {
218 pub fn name(&self) -> &str {
220 match self {
221 Self::Function(definition) => &definition.name,
222 Self::Modifier(definition) => &definition.name,
223 }
224 }
225
226 pub fn visibility(&self) -> &Visibility {
228 match self {
229 Self::Function(definition) => &definition.visibility,
230 Self::Modifier(definition) => &definition.visibility,
231 }
232 }
233
234 pub fn src(&self) -> &SourceLocation {
236 match self {
237 Self::Function(definition) => &definition.src,
238 Self::Modifier(definition) => &definition.src,
239 }
240 }
241
242 pub fn state_mutability(&self) -> Option<&StateMutability> {
244 match self {
245 Self::Function(definition) => definition.state_mutability.as_ref(),
246 Self::Modifier(_) => None,
247 }
248 }
249}
250
251impl Function {
252 pub fn new_function(contract: Option<ContractRef>, definition: FunctionDefinition) -> Self {
254 Self {
255 ufid: UFID::next(),
256 contract,
257 definition: FunctionVariant::Function(definition),
258 steps: vec![],
259 }
260 }
261
262 pub fn new_modifier(contract: ContractRef, definition: ModifierDefinition) -> Self {
264 Self {
265 ufid: UFID::next(),
266 contract: Some(contract),
267 definition: FunctionVariant::Modifier(definition),
268 steps: vec![],
269 }
270 }
271}