1use serde::{Deserialize, Serialize};
7
8pub fn parse_src(src: &str) -> (u64, u64, u64) {
10 let parts: Vec<&str> = src.split(':').collect();
11 let start = parts.first().and_then(|s| s.parse().ok()).unwrap_or(0);
12 let length = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(0);
13 let file = parts.get(2).and_then(|s| s.parse().ok()).unwrap_or(0);
14 (start, length, file)
15}
16
17pub fn offset_to_line(source: &str, byte_offset: u64) -> usize {
19 source[..std::cmp::min(byte_offset as usize, source.len())]
20 .chars()
21 .filter(|&c| c == '\n')
22 .count()
23 + 1
24}
25
26#[derive(Debug, Clone, Deserialize, Serialize)]
28pub struct SourceUnit {
29 pub id: u64,
31 pub src: String,
33 pub nodes: Vec<AstNode>,
35}
36
37#[derive(Debug, Clone, Deserialize, Serialize)]
39pub struct ContractDefinition {
40 pub id: u64,
42 pub src: String,
44 pub name: String,
46 #[serde(rename = "contractKind")]
48 pub contract_kind: String,
49 #[serde(rename = "baseContracts")]
51 pub base_contracts: Vec<InheritanceSpecifier>,
52 pub nodes: Vec<AstNode>,
54 #[serde(rename = "linearizedBaseContracts")]
56 pub linearized_base_contracts: Vec<u64>,
57}
58
59#[derive(Debug, Clone, Deserialize, Serialize)]
61pub struct InheritanceSpecifier {
62 #[serde(rename = "baseName")]
64 pub base_name: Identifier,
65}
66
67#[derive(Debug, Clone, Deserialize, Serialize)]
69pub struct FunctionDefinition {
70 pub id: u64,
72 pub src: String,
74 pub name: String,
76 pub visibility: String,
78 #[serde(rename = "stateMutability")]
80 pub state_mutability: String,
81 #[serde(rename = "isConstructor")]
83 pub is_constructor: bool,
84 pub modifiers: Vec<ModifierInvocation>,
86 pub parameters: ParameterList,
88 #[serde(rename = "returnParameters")]
90 pub return_parameters: ParameterList,
91 pub body: Option<Block>,
93}
94
95#[derive(Debug, Clone, Deserialize, Serialize)]
97pub struct ModifierInvocation {
98 #[serde(rename = "modifierName")]
100 pub modifier_name: Identifier,
101}
102
103#[derive(Debug, Clone, Deserialize, Serialize)]
105pub struct ParameterList {
106 pub parameters: Vec<VariableDeclaration>,
108}
109
110#[derive(Debug, Clone, Deserialize, Serialize)]
112pub struct VariableDeclaration {
113 pub id: u64,
115 pub src: String,
117 pub name: String,
119 #[serde(rename = "stateVariable")]
121 pub state_variable: bool,
122 pub visibility: String,
124 #[serde(rename = "storageLocation")]
126 pub storage_location: String,
127 #[serde(rename = "typeName")]
129 pub type_name: Option<Box<AstNode>>,
130 #[serde(rename = "typeDescriptions")]
132 pub type_descriptions: Option<TypeDescription>,
133}
134
135#[derive(Debug, Clone, Deserialize, Serialize)]
137pub struct TypeDescription {
138 #[serde(rename = "typeIdentifier")]
140 pub type_identifier: String,
141 #[serde(rename = "typeString")]
143 pub type_string: String,
144}
145
146#[derive(Debug, Clone, Deserialize, Serialize)]
148pub struct Block {
149 pub id: u64,
151 pub src: String,
153 pub statements: Vec<AstNode>,
155}
156
157#[derive(Debug, Clone, Deserialize, Serialize)]
159pub struct ExpressionStatement {
160 pub id: u64,
162 pub src: String,
164 pub expression: Option<Box<AstNode>>,
166}
167
168#[derive(Debug, Clone, Deserialize, Serialize)]
170pub struct IfStatement {
171 pub id: u64,
173 pub src: String,
175 pub condition: Box<AstNode>,
177 #[serde(rename = "trueBody")]
179 pub true_body: Box<AstNode>,
180 #[serde(rename = "falseBody")]
182 pub false_body: Option<Box<AstNode>>,
183}
184
185#[derive(Debug, Clone, Deserialize, Serialize)]
187pub struct ForStatement {
188 pub id: u64,
190 pub src: String,
192}
193
194#[derive(Debug, Clone, Deserialize, Serialize)]
196pub struct WhileStatement {
197 pub id: u64,
199 pub src: String,
201}
202
203#[derive(Debug, Clone, Deserialize, Serialize)]
205pub struct ReturnStatement {
206 pub id: u64,
208 pub src: String,
210}
211
212#[derive(Debug, Clone, Deserialize, Serialize)]
214pub struct Assignment {
215 pub id: u64,
217 pub src: String,
219 #[serde(rename = "leftHandSide")]
221 pub left_hand_side: Box<AstNode>,
222 pub operator: String,
224 #[serde(rename = "rightHandSide")]
226 pub right_hand_side: Box<AstNode>,
227}
228
229#[derive(Debug, Clone, Deserialize, Serialize)]
231pub struct FunctionCall {
232 pub id: u64,
234 pub src: String,
236 pub expression: Box<AstNode>,
238 pub arguments: Vec<AstNode>,
240 pub names: Vec<String>,
242 #[serde(rename = "tryCall")]
244 pub try_call: bool,
245}
246
247#[derive(Debug, Clone, Deserialize, Serialize)]
249pub struct MemberAccess {
250 pub id: u64,
252 pub src: String,
254 pub expression: Box<AstNode>,
256 #[serde(rename = "memberName")]
258 pub member_name: String,
259 #[serde(rename = "typeDescriptions")]
261 pub type_descriptions: Option<TypeDescription>,
262}
263
264#[derive(Debug, Clone, Deserialize, Serialize)]
266pub struct IndexAccess {
267 pub id: u64,
269 pub src: String,
271 #[serde(rename = "baseExpression")]
273 pub base_expression: Box<AstNode>,
274 #[serde(rename = "indexExpression")]
276 pub index_expression: Option<Box<AstNode>>,
277}
278
279#[derive(Debug, Clone, Deserialize, Serialize)]
281pub struct BinaryOperation {
282 pub id: u64,
284 pub src: String,
286 pub operator: String,
288 #[serde(rename = "leftExpression")]
290 pub left_expression: Box<AstNode>,
291 #[serde(rename = "rightExpression")]
293 pub right_expression: Box<AstNode>,
294 #[serde(rename = "commonType")]
296 pub common_type: Option<TypeDescription>,
297}
298
299#[derive(Debug, Clone, Deserialize, Serialize)]
301pub struct Identifier {
302 pub id: u64,
304 pub src: String,
306 pub name: String,
308 #[serde(rename = "referencedDeclaration")]
310 pub referenced_declaration: Option<u64>,
311 #[serde(rename = "typeDescriptions")]
313 pub type_descriptions: Option<TypeDescription>,
314}
315
316#[derive(Debug, Clone, Deserialize, Serialize)]
318pub struct Literal {
319 pub id: u64,
321 pub src: String,
323 pub value: String,
325 pub subdenomination: Option<String>,
327 #[serde(rename = "typeDescriptions")]
329 pub type_descriptions: Option<TypeDescription>,
330}
331
332#[derive(Debug, Clone, Deserialize, Serialize)]
334pub struct EmitStatement {
335 pub id: u64,
337 pub src: String,
339 #[serde(rename = "eventCall")]
341 pub event_call: Box<AstNode>,
342}
343
344#[derive(Debug, Clone, Deserialize, Serialize)]
346pub struct RevertStatement {
347 pub id: u64,
349 pub src: String,
351 #[serde(rename = "errorCall")]
353 pub error_call: Option<Box<AstNode>>,
354}
355
356#[derive(Debug, Clone, Deserialize, Serialize)]
358pub struct ModifierDefinition {
359 pub id: u64,
361 pub src: String,
363 pub name: String,
365 pub parameters: ParameterList,
367 pub body: Option<Block>,
369}
370
371#[derive(Debug, Clone, Deserialize, Serialize)]
373pub struct StateVariableDeclaration {
374 pub id: u64,
376 pub src: String,
378 pub variables: Vec<VariableDeclaration>,
380}
381
382#[derive(Debug, Clone, Deserialize, Serialize)]
384#[serde(tag = "nodeType")]
385pub enum AstNode {
386 #[serde(rename = "SourceUnit")]
388 SourceUnit(SourceUnit),
389 #[serde(rename = "ContractDefinition")]
391 ContractDefinition(ContractDefinition),
392 #[serde(rename = "FunctionDefinition")]
394 FunctionDefinition(FunctionDefinition),
395 #[serde(rename = "ModifierDefinition")]
397 ModifierDefinition(ModifierDefinition),
398 #[serde(rename = "VariableDeclarationStatement")]
400 StateVariableDeclaration(StateVariableDeclaration),
401 #[serde(rename = "ExpressionStatement")]
403 ExpressionStatement(ExpressionStatement),
404 #[serde(rename = "IfStatement")]
406 IfStatement(IfStatement),
407 #[serde(rename = "ForStatement")]
409 ForStatement(ForStatement),
410 #[serde(rename = "WhileStatement")]
412 WhileStatement(WhileStatement),
413 #[serde(rename = "Return")]
415 ReturnStatement(ReturnStatement),
416 #[serde(rename = "Assignment")]
418 Assignment(Assignment),
419 #[serde(rename = "FunctionCall")]
421 FunctionCall(FunctionCall),
422 #[serde(rename = "MemberAccess")]
424 MemberAccess(MemberAccess),
425 #[serde(rename = "IndexAccess")]
427 IndexAccess(IndexAccess),
428 #[serde(rename = "BinaryOperation")]
430 BinaryOperation(BinaryOperation),
431 #[serde(rename = "Identifier")]
433 Identifier(Identifier),
434 #[serde(rename = "Literal")]
436 Literal(Literal),
437 #[serde(rename = "Block")]
439 Block(Block),
440 #[serde(rename = "EmitStatement")]
442 EmitStatement(EmitStatement),
443 #[serde(rename = "RevertStatement")]
445 RevertStatement(RevertStatement),
446 #[serde(rename = "VariableDeclaration")]
448 VariableDeclaration(VariableDeclaration),
449 #[serde(other)]
451 Other,
452}
453
454impl AstNode {
455 pub fn get_type_string(&self) -> Option<String> {
457 match self {
458 AstNode::Identifier(id) => id.type_descriptions.as_ref().map(|t| t.type_string.clone()),
459 AstNode::Literal(lit) => lit
460 .type_descriptions
461 .as_ref()
462 .map(|t| t.type_string.clone()),
463 AstNode::MemberAccess(ma) => {
464 ma.type_descriptions.as_ref().map(|t| t.type_string.clone())
465 }
466 AstNode::BinaryOperation(bo) => bo.common_type.as_ref().map(|t| t.type_string.clone()),
467 _ => None,
468 }
469 }
470}