traverse_solidity/
ast.rs

1//! AST types for Solidity
2
3#[derive(Debug, Clone, PartialEq, Default)]
4pub struct SourceUnit {
5    pub items: Vec<SourceUnitItem>,
6}
7
8#[derive(Debug, Clone, PartialEq)]
9pub enum SourceUnitItem {
10    Pragma(PragmaDirective),
11    Import(ImportDirective),
12    Contract(ContractDefinition),
13    Interface(InterfaceDefinition),
14    Library(LibraryDefinition),
15    Function(FunctionDefinition),
16    ConstantVariable(ConstantVariableDeclaration),
17    Struct(StructDefinition),
18    Enum(EnumDefinition),
19    Error(ErrorDefinition),
20    Event(EventDefinition),
21    Using(UsingDirective),
22}
23
24#[derive(Debug, Clone, PartialEq)]
25pub struct PragmaDirective {
26    pub tokens: Vec<String>,
27}
28
29#[derive(Debug, Clone, PartialEq)]
30pub struct ImportDirective {
31    pub path: String,
32    pub alias: Option<String>,
33    pub symbols: Option<Vec<ImportSymbol>>,
34}
35
36#[derive(Debug, Clone, PartialEq)]
37pub struct ImportSymbol {
38    pub name: String,
39    pub alias: Option<String>,
40}
41
42#[derive(Debug, Clone, PartialEq)]
43pub struct ContractDefinition {
44    pub is_abstract: bool,
45    pub name: String,
46    pub inheritance: Vec<InheritanceSpecifier>,
47    pub body: Vec<ContractBodyElement>,
48}
49
50#[derive(Debug, Clone, PartialEq)]
51pub struct InterfaceDefinition {
52    pub name: String,
53    pub inheritance: Vec<InheritanceSpecifier>,
54    pub body: Vec<ContractBodyElement>,
55}
56
57#[derive(Debug, Clone, PartialEq)]
58pub struct LibraryDefinition {
59    pub name: String,
60    pub body: Vec<ContractBodyElement>,
61}
62
63#[derive(Debug, Clone, PartialEq)]
64pub struct InheritanceSpecifier {
65    pub name: IdentifierPath,
66    pub arguments: Option<Vec<Expression>>,
67}
68
69#[derive(Debug, Clone, PartialEq)]
70pub enum ContractBodyElement {
71    Constructor(ConstructorDefinition),
72    Function(FunctionDefinition),
73    Modifier(ModifierDefinition),
74    StateVariable(StateVariableDeclaration),
75    Event(EventDefinition),
76    Error(ErrorDefinition),
77    Struct(StructDefinition),
78    Enum(EnumDefinition),
79    Using(UsingDirective),
80}
81
82#[derive(Debug, Clone, PartialEq)]
83pub struct FunctionDefinition {
84    pub name: Option<String>,
85    pub parameters: Vec<Parameter>,
86    pub visibility: Option<Visibility>,
87    pub state_mutability: Option<StateMutability>,
88    pub modifiers: Vec<ModifierInvocation>,
89    pub is_virtual: bool,
90    pub override_specifier: Option<OverrideSpecifier>,
91    pub returns: Option<Vec<Parameter>>,
92    pub body: Option<Block>,
93}
94
95#[derive(Debug, Clone, PartialEq)]
96pub struct ConstructorDefinition {
97    pub parameters: Vec<Parameter>,
98    pub modifiers: Vec<ModifierInvocation>,
99    pub is_payable: bool,
100    pub visibility: Option<Visibility>,
101    pub body: Block,
102}
103
104#[derive(Debug, Clone, PartialEq)]
105pub struct ModifierDefinition {
106    pub name: String,
107    pub parameters: Vec<Parameter>,
108    pub is_virtual: bool,
109    pub override_specifier: Option<OverrideSpecifier>,
110    pub body: Option<Block>,
111}
112
113#[derive(Debug, Clone, PartialEq)]
114pub struct StateVariableDeclaration {
115    pub type_name: TypeName,
116    pub visibility: Option<Visibility>,
117    pub is_constant: bool,
118    pub is_immutable: bool,
119    pub is_transient: bool,
120    pub override_specifier: Option<OverrideSpecifier>,
121    pub name: String,
122    pub initial_value: Option<Expression>,
123}
124
125#[derive(Debug, Clone, PartialEq)]
126pub struct ConstantVariableDeclaration {
127    pub type_name: TypeName,
128    pub name: String,
129    pub initial_value: Expression,
130}
131
132#[derive(Debug, Clone, PartialEq)]
133pub struct StructDefinition {
134    pub name: String,
135    pub members: Vec<StructMember>,
136}
137
138#[derive(Debug, Clone, PartialEq)]
139pub struct StructMember {
140    pub type_name: TypeName,
141    pub name: String,
142}
143
144#[derive(Debug, Clone, PartialEq)]
145pub struct EnumDefinition {
146    pub name: String,
147    pub values: Vec<String>,
148}
149
150#[derive(Debug, Clone, PartialEq)]
151pub struct EventDefinition {
152    pub name: String,
153    pub parameters: Vec<EventParameter>,
154    pub is_anonymous: bool,
155}
156
157#[derive(Debug, Clone, PartialEq)]
158pub struct EventParameter {
159    pub type_name: TypeName,
160    pub is_indexed: bool,
161    pub name: Option<String>,
162}
163
164#[derive(Debug, Clone, PartialEq)]
165pub struct ErrorDefinition {
166    pub name: String,
167    pub parameters: Vec<ErrorParameter>,
168}
169
170#[derive(Debug, Clone, PartialEq)]
171pub struct ErrorParameter {
172    pub type_name: TypeName,
173    pub name: Option<String>,
174}
175
176#[derive(Debug, Clone, PartialEq)]
177pub struct UsingDirective {
178    pub library: IdentifierPath,
179    pub type_name: Option<TypeName>,
180    pub is_global: bool,
181}
182
183#[derive(Debug, Clone, PartialEq)]
184pub struct Parameter {
185    pub type_name: TypeName,
186    pub data_location: Option<DataLocation>,
187    pub name: Option<String>,
188}
189
190#[derive(Debug, Clone, PartialEq)]
191pub struct ModifierInvocation {
192    pub name: IdentifierPath,
193    pub arguments: Option<Vec<Expression>>,
194}
195
196#[derive(Debug, Clone, PartialEq)]
197pub struct OverrideSpecifier {
198    pub overrides: Vec<IdentifierPath>,
199}
200
201#[derive(Debug, Clone, PartialEq)]
202pub enum Visibility {
203    Public,
204    Private,
205    Internal,
206    External,
207}
208
209#[derive(Debug, Clone, PartialEq)]
210pub enum StateMutability {
211    Pure,
212    View,
213    Payable,
214}
215
216#[derive(Debug, Clone, PartialEq)]
217pub enum DataLocation {
218    Memory,
219    Storage,
220    Calldata,
221}
222
223#[derive(Debug, Clone, PartialEq)]
224pub enum TypeName {
225    Elementary(ElementaryTypeName),
226    UserDefined(IdentifierPath),
227    Array(Box<TypeName>, Option<Box<Expression>>), // Fixed recursion with Box
228    Mapping(MappingType),
229    Function(FunctionTypeName),
230}
231
232#[derive(Debug, Clone, PartialEq)]
233pub enum ElementaryTypeName {
234    Address,
235    AddressPayable,
236    Bool,
237    String,
238    Bytes,
239    SignedInteger(Option<u16>), // bit size
240    UnsignedInteger(Option<u16>), // bit size
241    FixedBytes(Option<u8>), // byte size
242    Fixed,
243    Ufixed,
244}
245
246#[derive(Debug, Clone, PartialEq)]
247pub struct MappingType {
248    pub key_type: Box<TypeName>,
249    pub key_name: Option<String>,
250    pub value_type: Box<TypeName>,
251    pub value_name: Option<String>,
252}
253
254#[derive(Debug, Clone, PartialEq)]
255pub struct FunctionTypeName {
256    pub parameters: Vec<Parameter>,
257    pub visibility: Option<Visibility>,
258    pub state_mutability: Option<StateMutability>,
259    pub returns: Option<Vec<Parameter>>,
260}
261
262#[derive(Debug, Clone, PartialEq)]
263pub struct IdentifierPath {
264    pub parts: Vec<String>,
265}
266
267impl IdentifierPath {
268    pub fn new(parts: Vec<String>) -> Self {
269        Self { parts }
270    }
271    
272    pub fn single(name: String) -> Self {
273        Self { parts: vec![name] }
274    }
275}
276
277#[derive(Debug, Clone, PartialEq)]
278pub enum Expression {
279    Identifier(String),
280    Literal(Literal),
281    Binary(BinaryExpression),
282    Unary(UnaryExpression),
283    FunctionCall(FunctionCallExpression),
284    MemberAccess(MemberAccessExpression),
285    IndexAccess(IndexAccessExpression),
286    Conditional(ConditionalExpression),
287    Assignment(AssignmentExpression),
288    Tuple(TupleExpression),
289    Array(ArrayExpression),
290    TypeConversion(Box<TypeConversionExpression>), // Fixed recursion with Box
291    New(NewExpression),
292}
293
294#[derive(Debug, Clone, PartialEq)]
295pub struct BinaryExpression {
296    pub left: Box<Expression>,
297    pub operator: BinaryOperator,
298    pub right: Box<Expression>,
299}
300
301#[derive(Debug, Clone, PartialEq)]
302pub enum BinaryOperator {
303    Add,
304    Sub,
305    Mul,
306    Div,
307    Mod,
308    Exp,
309    Equal,
310    NotEqual,
311    LessThan,
312    LessThanOrEqual,
313    GreaterThan,
314    GreaterThanOrEqual,
315    And,
316    Or,
317    BitAnd,
318    BitOr,
319    BitXor,
320    ShiftLeft,
321    ShiftRight,
322    ShiftRightArithmetic,
323}
324
325#[derive(Debug, Clone, PartialEq)]
326pub struct UnaryExpression {
327    pub operator: UnaryOperator,
328    pub operand: Box<Expression>,
329    pub is_prefix: bool,
330}
331
332#[derive(Debug, Clone, PartialEq)]
333pub enum UnaryOperator {
334    Plus,
335    Minus,
336    Not,
337    BitNot,
338    Increment,
339    Decrement,
340    Delete,
341}
342
343#[derive(Debug, Clone, PartialEq)]
344pub struct FunctionCallExpression {
345    pub function: Box<Expression>,
346    pub arguments: Vec<Expression>,
347}
348
349#[derive(Debug, Clone, PartialEq)]
350pub struct MemberAccessExpression {
351    pub object: Box<Expression>,
352    pub member: String,
353}
354
355#[derive(Debug, Clone, PartialEq)]
356pub struct IndexAccessExpression {
357    pub object: Box<Expression>,
358    pub index: Option<Box<Expression>>,
359}
360
361#[derive(Debug, Clone, PartialEq)]
362pub struct ConditionalExpression {
363    pub condition: Box<Expression>,
364    pub true_expr: Box<Expression>,
365    pub false_expr: Box<Expression>,
366}
367
368#[derive(Debug, Clone, PartialEq)]
369pub struct AssignmentExpression {
370    pub left: Box<Expression>,
371    pub operator: AssignmentOperator,
372    pub right: Box<Expression>,
373}
374
375#[derive(Debug, Clone, PartialEq)]
376pub enum AssignmentOperator {
377    Assign,
378    AddAssign,
379    SubAssign,
380    MulAssign,
381    DivAssign,
382    ModAssign,
383    BitAndAssign,
384    BitOrAssign,
385    BitXorAssign,
386    ShiftLeftAssign,
387    ShiftRightAssign,
388    ShiftRightArithmeticAssign,
389}
390
391#[derive(Debug, Clone, PartialEq)]
392pub struct TupleExpression {
393    pub elements: Vec<Option<Expression>>,
394}
395
396#[derive(Debug, Clone, PartialEq)]
397pub struct ArrayExpression {
398    pub elements: Vec<Expression>,
399}
400
401#[derive(Debug, Clone, PartialEq)]
402pub struct TypeConversionExpression {
403    pub type_name: Box<TypeName>, // Fixed recursion with Box
404    pub expression: Box<Expression>,
405}
406
407#[derive(Debug, Clone, PartialEq)]
408pub struct NewExpression {
409    pub type_name: TypeName,
410}
411
412#[derive(Debug, Clone, PartialEq)]
413pub enum Literal {
414    Boolean(bool),
415    Number(NumberLiteral),
416    String(StringLiteral),
417    HexString(HexStringLiteral),
418    UnicodeString(UnicodeStringLiteral),
419}
420
421#[derive(Debug, Clone, PartialEq)]
422pub struct NumberLiteral {
423    pub value: String,
424    pub sub_denomination: Option<String>,
425}
426
427#[derive(Debug, Clone, PartialEq)]
428pub struct StringLiteral {
429    pub value: String,
430}
431
432#[derive(Debug, Clone, PartialEq)]
433pub struct HexStringLiteral {
434    pub value: String,
435}
436
437#[derive(Debug, Clone, PartialEq)]
438pub struct UnicodeStringLiteral {
439    pub value: String,
440}
441
442#[derive(Debug, Clone, PartialEq)]
443pub enum Statement {
444    Block(Block),
445    Expression(ExpressionStatement),
446    Variable(VariableDeclarationStatement),
447    If(IfStatement),
448    For(ForStatement),
449    While(WhileStatement),
450    DoWhile(DoWhileStatement),
451    Continue(ContinueStatement),
452    Break(BreakStatement),
453    Return(ReturnStatement),
454    Emit(EmitStatement),
455    Revert(RevertStatement),
456    Try(TryStatement),
457    Assembly(AssemblyStatement),
458    Unchecked(UncheckedBlock),
459}
460
461#[derive(Debug, Clone, PartialEq)]
462pub struct Block {
463    pub statements: Vec<Statement>,
464}
465
466#[derive(Debug, Clone, PartialEq)]
467pub struct ExpressionStatement {
468    pub expression: Expression,
469}
470
471#[derive(Debug, Clone, PartialEq)]
472pub struct VariableDeclarationStatement {
473    pub declaration: VariableDeclaration,
474    pub initial_value: Option<Expression>,
475}
476
477#[derive(Debug, Clone, PartialEq)]
478pub struct VariableDeclaration {
479    pub type_name: TypeName,
480    pub data_location: Option<DataLocation>,
481    pub name: String,
482}
483
484#[derive(Debug, Clone, PartialEq)]
485pub struct IfStatement {
486    pub condition: Expression,
487    pub then_statement: Box<Statement>,
488    pub else_statement: Option<Box<Statement>>,
489}
490
491#[derive(Debug, Clone, PartialEq)]
492pub struct ForStatement {
493    pub init: Option<Box<Statement>>,
494    pub condition: Option<Expression>,
495    pub update: Option<Expression>,
496    pub body: Box<Statement>,
497}
498
499#[derive(Debug, Clone, PartialEq)]
500pub struct WhileStatement {
501    pub condition: Expression,
502    pub body: Box<Statement>,
503}
504
505#[derive(Debug, Clone, PartialEq)]
506pub struct DoWhileStatement {
507    pub body: Box<Statement>,
508    pub condition: Expression,
509}
510
511#[derive(Debug, Clone, PartialEq)]
512pub struct ContinueStatement;
513
514#[derive(Debug, Clone, PartialEq)]
515pub struct BreakStatement;
516
517#[derive(Debug, Clone, PartialEq)]
518pub struct ReturnStatement {
519    pub expression: Option<Expression>,
520}
521
522#[derive(Debug, Clone, PartialEq)]
523pub struct EmitStatement {
524    pub event_call: Expression,
525}
526
527#[derive(Debug, Clone, PartialEq)]
528pub struct RevertStatement {
529    pub error_call: Expression,
530}
531
532#[derive(Debug, Clone, PartialEq)]
533pub struct TryStatement {
534    pub expression: Expression,
535    pub returns: Option<Vec<Parameter>>,
536    pub body: Block,
537    pub catch_clauses: Vec<CatchClause>,
538}
539
540#[derive(Debug, Clone, PartialEq)]
541pub struct CatchClause {
542    pub identifier: Option<String>,
543    pub parameters: Option<Vec<Parameter>>,
544    pub body: Block,
545}
546
547#[derive(Debug, Clone, PartialEq)]
548pub struct AssemblyStatement {
549    pub dialect: Option<String>,
550    pub flags: Vec<String>,
551    pub body: YulBlock,
552}
553
554#[derive(Debug, Clone, PartialEq)]
555pub struct UncheckedBlock {
556    pub body: Block,
557}
558
559#[derive(Debug, Clone, PartialEq)]
560pub struct YulBlock {
561    pub statements: Vec<YulStatement>,
562}
563
564#[derive(Debug, Clone, PartialEq)]
565pub enum YulStatement {
566    Block(YulBlock),
567    VariableDeclaration(YulVariableDeclaration),
568    Assignment(YulAssignment),
569    FunctionCall(YulFunctionCall),
570    If(YulIfStatement),
571    For(YulForStatement),
572    Switch(YulSwitchStatement),
573    FunctionDefinition(YulFunctionDefinition),
574    Leave,
575    Break,
576    Continue,
577}
578
579#[derive(Debug, Clone, PartialEq)]
580pub struct YulVariableDeclaration {
581    pub variables: Vec<String>,
582    pub expression: Option<YulExpression>,
583}
584
585#[derive(Debug, Clone, PartialEq)]
586pub struct YulAssignment {
587    pub variables: Vec<YulPath>,
588    pub expression: YulExpression,
589}
590
591#[derive(Debug, Clone, PartialEq)]
592pub struct YulFunctionCall {
593    pub function: String,
594    pub arguments: Vec<YulExpression>,
595}
596
597#[derive(Debug, Clone, PartialEq)]
598pub struct YulIfStatement {
599    pub condition: YulExpression,
600    pub body: YulBlock,
601}
602
603#[derive(Debug, Clone, PartialEq)]
604pub struct YulForStatement {
605    pub init: YulBlock,
606    pub condition: YulExpression,
607    pub post: YulBlock,
608    pub body: YulBlock,
609}
610
611#[derive(Debug, Clone, PartialEq)]
612pub struct YulSwitchStatement {
613    pub expression: YulExpression,
614    pub cases: Vec<YulSwitchCase>,
615    pub default: Option<YulBlock>,
616}
617
618#[derive(Debug, Clone, PartialEq)]
619pub struct YulSwitchCase {
620    pub value: YulLiteral,
621    pub body: YulBlock,
622}
623
624#[derive(Debug, Clone, PartialEq)]
625pub struct YulFunctionDefinition {
626    pub name: String,
627    pub parameters: Vec<String>,
628    pub returns: Vec<String>,
629    pub body: YulBlock,
630}
631
632#[derive(Debug, Clone, PartialEq)]
633pub struct YulPath {
634    pub parts: Vec<String>,
635}
636
637#[derive(Debug, Clone, PartialEq)]
638pub enum YulExpression {
639    Path(YulPath),
640    FunctionCall(YulFunctionCall),
641    Literal(YulLiteral),
642}
643
644#[derive(Debug, Clone, PartialEq)]
645pub enum YulLiteral {
646    Number(String),
647    String(String),
648    HexNumber(String),
649    Boolean(bool),
650    HexString(String),
651}