ethers_solc/artifacts/ast/
mod.rs

1//! Bindings for the Solidity and Yul ASTs.
2//!
3//! The Yul AST bindings are available in the [yul] module.
4//!
5//! To gain an overview of the AST, it might be helpful to start at the entry point of a complete
6//! Solidity AST: the [SourceUnit] node.
7//!
8//! # Version Support
9//!
10//! These types should be compatible with at least Solidity 0.5.x and above, but may also support
11//! 0.4.x-0.5.x in most cases.
12//!
13//! The legacy Solidity AST is not supported.
14mod macros;
15mod misc;
16pub use misc::*;
17pub mod util;
18pub mod visitor;
19
20/// A low fidelity representation of the AST.
21pub(crate) mod lowfidelity;
22pub use lowfidelity::{Ast, Node, NodeType, SourceLocation as LowFidelitySourceLocation};
23
24/// Types for the Yul AST.
25///
26/// The Yul AST is embedded into the Solidity AST for inline assembly blocks.
27pub mod yul;
28
29use crate::artifacts::serde_helpers;
30use macros::{ast_node, expr_node, node_group, stmt_node};
31use serde::{Deserialize, Serialize};
32use std::collections::BTreeMap;
33use yul::YulBlock;
34
35ast_node!(
36    /// The root node of a Solidity AST.
37    struct SourceUnit {
38        #[serde(rename = "absolutePath")]
39        absolute_path: String,
40        #[serde(default, rename = "exportedSymbols")]
41        exported_symbols: BTreeMap<String, Vec<usize>>,
42        #[serde(default)]
43        license: Option<String>,
44        #[serde(default, skip_serializing_if = "Vec::is_empty")]
45        nodes: Vec<SourceUnitPart>,
46    }
47);
48
49node_group! {
50    SourceUnitPart;
51
52    PragmaDirective,
53    ImportDirective,
54    UsingForDirective,
55    VariableDeclaration,
56    EnumDefinition,
57    ErrorDefinition,
58    FunctionDefinition,
59    StructDefinition,
60    UserDefinedValueTypeDefinition,
61    ContractDefinition,
62}
63
64node_group! {
65    Expression;
66
67    Assignment,
68    BinaryOperation,
69    Conditional,
70    ElementaryTypeNameExpression,
71    FunctionCall,
72    FunctionCallOptions,
73    Identifier,
74    IndexAccess,
75    IndexRangeAccess,
76    Literal,
77    MemberAccess,
78    NewExpression,
79    TupleExpression,
80    UnaryOperation,
81}
82
83node_group! {
84    Statement;
85
86    Block,
87    Break,
88    Continue,
89    DoWhileStatement,
90    EmitStatement,
91    ExpressionStatement,
92    ForStatement,
93    IfStatement,
94    InlineAssembly,
95    PlaceholderStatement,
96    Return,
97    RevertStatement,
98    TryStatement,
99    UncheckedBlock,
100    VariableDeclarationStatement,
101    WhileStatement,
102
103}
104
105node_group! {
106    ContractDefinitionPart;
107
108    EnumDefinition,
109    ErrorDefinition,
110    EventDefinition,
111    FunctionDefinition,
112    ModifierDefinition,
113    StructDefinition,
114    UserDefinedValueTypeDefinition,
115    UsingForDirective,
116    VariableDeclaration,
117}
118
119node_group! {
120    TypeName;
121
122    ArrayTypeName,
123    ElementaryTypeName,
124    FunctionTypeName,
125    Mapping,
126    UserDefinedTypeName,
127}
128
129// TODO: Better name
130node_group! {
131    UserDefinedTypeNameOrIdentifierPath;
132
133    UserDefinedTypeName,
134    IdentifierPath,
135}
136
137// TODO: Better name
138#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
139#[serde(untagged)]
140pub enum BlockOrStatement {
141    Statement(Statement),
142    Block(Block),
143}
144
145// TODO: Better name
146node_group! {
147    ExpressionOrVariableDeclarationStatement;
148
149    ExpressionStatement,
150    VariableDeclarationStatement
151}
152
153// TODO: Better name
154node_group! {
155    IdentifierOrIdentifierPath;
156
157    Identifier,
158    IdentifierPath
159}
160
161ast_node!(
162    /// A contract definition.
163    struct ContractDefinition {
164        name: String,
165        #[serde(default, with = "serde_helpers::display_from_str_opt")]
166        name_location: Option<SourceLocation>,
167        #[serde(default, rename = "abstract")]
168        is_abstract: bool,
169        base_contracts: Vec<InheritanceSpecifier>,
170        canonical_name: Option<String>,
171        contract_dependencies: Vec<usize>,
172        #[serde(rename = "contractKind")]
173        kind: ContractKind,
174        documentation: Option<StructuredDocumentation>,
175        fully_implemented: bool,
176        linearized_base_contracts: Vec<usize>,
177        nodes: Vec<ContractDefinitionPart>,
178        scope: usize,
179        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
180        used_errors: Vec<usize>,
181        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
182        used_events: Vec<usize>,
183        #[serde(default, rename = "internalFunctionIDs")]
184        internal_function_ids: BTreeMap<usize, usize>,
185    }
186);
187
188/// All Solidity contract kinds.
189#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
190#[serde(rename_all = "camelCase")]
191pub enum ContractKind {
192    /// A normal contract.
193    Contract,
194    /// An interface.
195    Interface,
196    /// A library.
197    Library,
198}
199
200ast_node!(
201    /// An inheritance specifier.
202    struct InheritanceSpecifier {
203        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
204        arguments: Vec<Expression>,
205        base_name: UserDefinedTypeNameOrIdentifierPath,
206    }
207);
208
209expr_node!(
210    /// An assignment expression.
211    struct Assignment {
212        #[serde(rename = "leftHandSide")]
213        lhs: Expression,
214        operator: AssignmentOperator,
215        #[serde(rename = "rightHandSide")]
216        rhs: Expression,
217    }
218);
219
220/// Assignment operators.
221#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
222pub enum AssignmentOperator {
223    /// Simple assignment (`=`)
224    #[serde(rename = "=")]
225    Assign,
226    /// Add and assign (`+=`)
227    #[serde(rename = "+=")]
228    AddAssign,
229    /// Subtract and assign (`-=`)
230    #[serde(rename = "-=")]
231    SubAssign,
232    /// Multiply and assign (`*=`)
233    #[serde(rename = "*=")]
234    MulAssign,
235    /// Divide and assign (`/=`)
236    #[serde(rename = "/=")]
237    DivAssign,
238    /// Modulo and assign (`%=`)
239    #[serde(rename = "%=")]
240    ModAssign,
241    /// Bitwise or and assign (`|=`)
242    #[serde(rename = "|=")]
243    OrAssign,
244    /// Bitwise and and assign (`&=`)
245    #[serde(rename = "&=")]
246    AndAssign,
247    /// Bitwise xor and assign (`^=`)
248    #[serde(rename = "^=")]
249    XorAssign,
250    /// Right shift and assign (`>>=`)
251    #[serde(rename = ">>=")]
252    ShrAssign,
253    /// Left shift and assign (`<<=`)
254    #[serde(rename = "<<=")]
255    ShlAssign,
256}
257
258ast_node!(
259    /// A binary operation.
260    struct BinaryOperation {
261        common_type: TypeDescriptions,
262        #[serde(rename = "leftExpression")]
263        lhs: Expression,
264        operator: BinaryOperator,
265        #[serde(rename = "rightExpression")]
266        rhs: Expression,
267    }
268);
269
270/// Binary operators.
271#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
272pub enum BinaryOperator {
273    /// Addition (`+`)
274    #[serde(rename = "+")]
275    Add,
276    /// Subtraction (`-`)
277    #[serde(rename = "-")]
278    Sub,
279    /// Multiplication (`*`)
280    #[serde(rename = "*")]
281    Mul,
282    /// Division (`/`)
283    #[serde(rename = "/")]
284    Div,
285    /// Modulo (`%`)
286    #[serde(rename = "%")]
287    Mod,
288    /// Exponentiation (`**`)
289    #[serde(rename = "**")]
290    Pow,
291    /// Logical and (`&&`)
292    #[serde(rename = "&&")]
293    And,
294    /// Logical or (`||`)
295    #[serde(rename = "||")]
296    Or,
297    /// Not equals (`!=`)
298    #[serde(rename = "!=")]
299    NotEqual,
300    /// Equals (`==`)
301    #[serde(rename = "==")]
302    Equal,
303    /// Less than (`<`)
304    #[serde(rename = "<")]
305    LessThan,
306    /// Less than or equal (`<=`)
307    #[serde(rename = "<=")]
308    LessThanOrEqual,
309    /// Greater than (`>`)
310    #[serde(rename = ">")]
311    GreaterThan,
312    /// Greater than or equal (`>=`)
313    #[serde(rename = ">=")]
314    GreaterThanOrEqual,
315    /// Bitwise xor (`^`)
316    #[serde(rename = "^")]
317    Xor,
318    /// Bitwise not (`~`)
319    #[serde(rename = "~")]
320    BitNot,
321    /// Bitwise and (`&`)
322    #[serde(rename = "&")]
323    BitAnd,
324    /// Bitwise or (`|`)
325    #[serde(rename = "|")]
326    BitOr,
327    /// Shift left (`<<`)
328    #[serde(rename = "<<")]
329    Shl,
330    /// Shift right (`>>`)
331    #[serde(rename = ">>")]
332    Shr,
333}
334
335expr_node!(
336    /// A conditional expression.
337    struct Conditional {
338        /// The condition.
339        condition: Expression,
340        /// The expression to evaluate if falsy.
341        false_expression: Expression,
342        /// The expression to evaluate if truthy.
343        true_expression: Expression,
344    }
345);
346
347expr_node!(
348    struct ElementaryTypeNameExpression {
349        type_name: ElementaryOrRawTypeName,
350    }
351);
352
353// TODO: Better name
354#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
355#[serde(untagged)]
356pub enum ElementaryOrRawTypeName {
357    /// An [ElementaryTypeName] node that describes the type.
358    ///
359    /// This variant applies to newer compiler versions.
360    ElementaryTypeName(ElementaryTypeName),
361    /// A string representing the type name.
362    ///
363    /// This variant applies to older compiler versions.
364    Raw(String),
365}
366
367ast_node!(
368    struct ElementaryTypeName {
369        type_descriptions: TypeDescriptions,
370        name: String,
371        state_mutability: Option<StateMutability>,
372    }
373);
374
375expr_node!(
376    /// A function call expression.
377    struct FunctionCall {
378        arguments: Vec<Expression>,
379        expression: Expression,
380        kind: FunctionCallKind,
381        names: Vec<String>,
382        #[serde(default)]
383        try_call: bool,
384    }
385);
386
387/// Function call kinds.
388#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
389#[serde(rename_all = "camelCase")]
390pub enum FunctionCallKind {
391    /// A regular function call.
392    FunctionCall,
393    /// A type conversion (e.g. `bytes(x)`).
394    TypeConversion,
395    /// A struct constructor call (e.g. `MyStruct({ ... })`).
396    StructConstructorCall,
397}
398
399expr_node!(
400    /// A function call options expression (e.g. `x.f{gas: 1}`).
401    struct FunctionCallOptions {
402        expression: Expression,
403        names: Vec<String>,
404        options: Vec<Expression>,
405    }
406);
407
408ast_node!(
409    /// An identifier.
410    struct Identifier {
411        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
412        argument_types: Vec<TypeDescriptions>,
413        name: String,
414        overloaded_declarations: Vec<isize>,
415        referenced_declaration: Option<isize>,
416        type_descriptions: TypeDescriptions,
417    }
418);
419
420expr_node!(
421    /// An index access.
422    struct IndexAccess {
423        base_expression: Expression,
424        index_expression: Option<Expression>,
425    }
426);
427
428expr_node!(
429    /// An index range access.
430    struct IndexRangeAccess {
431        base_expression: Expression,
432        start_expression: Option<Expression>,
433        end_expression: Option<Expression>,
434    }
435);
436
437expr_node!(
438    /// A literal value.
439    struct Literal {
440        // TODO
441        hex_value: String,
442        kind: LiteralKind,
443        subdenomination: Option<String>, // TODO
444        value: Option<String>,           // TODO
445    }
446);
447
448/// Literal kinds.
449#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
450#[serde(rename_all = "camelCase")]
451pub enum LiteralKind {
452    /// A boolean.
453    Bool,
454    /// A number.
455    Number,
456    /// A string.
457    String,
458    /// A hexadecimal string.
459    HexString,
460    /// A unicode string.
461    UnicodeString,
462}
463
464expr_node!(
465    /// Member access.
466    struct MemberAccess {
467        expression: Expression,
468        member_name: String,
469        referenced_declaration: Option<isize>,
470    }
471);
472
473expr_node!(
474    /// A `new` expression.
475    struct NewExpression {
476        type_name: TypeName,
477    }
478);
479
480ast_node!(
481    /// An array type name.
482    struct ArrayTypeName {
483        type_descriptions: TypeDescriptions,
484        base_type: TypeName,
485        length: Option<Expression>,
486    }
487);
488
489ast_node!(
490    /// A function type name.
491    struct FunctionTypeName {
492        type_descriptions: TypeDescriptions,
493        parameter_types: ParameterList,
494        return_parameter_types: ParameterList,
495        state_mutability: StateMutability,
496        visibility: Visibility,
497    }
498);
499
500ast_node!(
501    /// A parameter list.
502    struct ParameterList {
503        parameters: Vec<VariableDeclaration>,
504    }
505);
506
507ast_node!(
508    /// A variable declaration.
509    struct VariableDeclaration {
510        name: String,
511        #[serde(default, with = "serde_helpers::display_from_str_opt")]
512        name_location: Option<SourceLocation>,
513        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
514        base_functions: Vec<usize>,
515        /// Marks whether or not the variable is a constant before Solidity 0.7.x.
516        ///
517        /// After 0.7.x you must use `mutability`. For cross-version compatibility use
518        /// [`VariableDeclaration::mutability()`].
519        #[serde(default)]
520        constant: bool,
521        /// Marks whether or not the variable is a state variable before Solidity 0.7.x.
522        ///
523        /// After 0.7.x you must use `mutability`. For cross-version compatibility use
524        /// [`VariableDeclaration::mutability()`].
525        #[serde(default)]
526        state_variable: bool,
527        documentation: Option<StructuredDocumentation>,
528        function_selector: Option<String>, // TODO
529        #[serde(default)]
530        indexed: bool,
531        /// Marks the variable's mutability from Solidity 0.7.x onwards.
532        /// For cross-version compatibility use [`VariableDeclaration::mutability()`].
533        #[serde(default)]
534        mutability: Option<Mutability>,
535        overrides: Option<OverrideSpecifier>,
536        scope: usize,
537        storage_location: StorageLocation,
538        type_descriptions: TypeDescriptions,
539        type_name: Option<TypeName>,
540        value: Option<Expression>,
541        visibility: Visibility,
542    }
543);
544
545impl VariableDeclaration {
546    /// Returns the mutability of the variable that was declared.
547    ///
548    /// This is a helper to check variable mutability across Solidity versions.
549    pub fn mutability(&self) -> &Mutability {
550        if let Some(mutability) = &self.mutability {
551            mutability
552        } else if self.constant {
553            &Mutability::Constant
554        } else if self.state_variable {
555            &Mutability::Mutable
556        } else {
557            unreachable!()
558        }
559    }
560}
561
562/// Structured documentation (NatSpec).
563#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
564#[serde(untagged)]
565pub enum StructuredDocumentation {
566    /// The documentation is provided in the form of an AST node.
567    Parsed { text: String },
568    /// The documentation is provided in the form of a string literal.
569    Text(String),
570}
571
572ast_node!(
573    /// An override specifier.
574    struct OverrideSpecifier {
575        overrides: Vec<UserDefinedTypeNameOrIdentifierPath>,
576    }
577);
578
579ast_node!(
580    /// A user defined type name.
581    struct UserDefinedTypeName {
582        type_descriptions: TypeDescriptions,
583        contract_scope: Option<String>, // TODO
584        name: Option<String>,
585        path_node: Option<IdentifierPath>,
586        referenced_declaration: isize,
587    }
588);
589
590ast_node!(
591    /// An identifier path.
592    struct IdentifierPath {
593        name: String,
594        referenced_declaration: isize,
595    }
596);
597
598ast_node!(
599    /// A mapping type.
600    struct Mapping {
601        type_descriptions: TypeDescriptions,
602        key_type: TypeName,
603        value_type: TypeName,
604    }
605);
606
607expr_node!(
608    /// A tuple expression.
609    struct TupleExpression {
610        components: Vec<Option<Expression>>,
611        is_inline_array: bool,
612    }
613);
614
615expr_node!(
616    /// A unary operation.
617    struct UnaryOperation {
618        operator: UnaryOperator,
619        /// Whether the unary operator is before or after the expression (e.g. `x++` vs. `++x`)
620        prefix: bool,
621        sub_expression: Expression,
622    }
623);
624
625/// Unary operators.
626#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
627pub enum UnaryOperator {
628    /// Increment (`++`)
629    #[serde(rename = "++")]
630    Increment,
631    /// Decrement (`--`)
632    #[serde(rename = "--")]
633    Decrement,
634    /// Negate (`-`)
635    #[serde(rename = "-")]
636    Negate,
637    /// Not (`!`)
638    #[serde(rename = "!")]
639    Not,
640    /// Bitwise not (`~`)
641    #[serde(rename = "~")]
642    BitNot,
643    /// `delete`
644    #[serde(rename = "delete")]
645    Delete,
646}
647
648ast_node!(
649    /// An enum definition.
650    struct EnumDefinition {
651        name: String,
652        #[serde(default, with = "serde_helpers::display_from_str_opt")]
653        name_location: Option<SourceLocation>,
654        canonical_name: String,
655        members: Vec<EnumValue>,
656    }
657);
658
659ast_node!(
660    /// An enum value.
661    struct EnumValue {
662        name: String,
663        #[serde(default, with = "serde_helpers::display_from_str_opt")]
664        name_location: Option<SourceLocation>,
665    }
666);
667
668ast_node!(
669    /// A custom error definition.
670    struct ErrorDefinition {
671        name: String,
672        #[serde(default, with = "serde_helpers::display_from_str_opt")]
673        name_location: Option<SourceLocation>,
674        documentation: Option<StructuredDocumentation>,
675        error_selector: Option<String>, // TODO
676        parameters: ParameterList,
677    }
678);
679
680ast_node!(
681    /// An event definition.
682    struct EventDefinition {
683        name: String,
684        #[serde(default, with = "serde_helpers::display_from_str_opt")]
685        name_location: Option<SourceLocation>,
686        anonymous: bool,
687        event_selector: Option<String>, // TODO
688        documentation: Option<StructuredDocumentation>,
689        parameters: ParameterList,
690    }
691);
692
693ast_node!(
694    /// A function definition.
695    struct FunctionDefinition {
696        name: String,
697        #[serde(default, with = "serde_helpers::display_from_str_opt")]
698        name_location: Option<SourceLocation>,
699        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
700        base_functions: Vec<usize>,
701        body: Option<Block>,
702        documentation: Option<StructuredDocumentation>,
703        function_selector: Option<String>, // TODO
704        implemented: bool,
705        modifiers: Vec<ModifierInvocation>,
706        overrides: Option<OverrideSpecifier>,
707        parameters: ParameterList,
708        return_parameters: ParameterList,
709        scope: usize,
710        visibility: Visibility,
711        /// The kind of function this node defines. Only valid for Solidity versions 0.5.x and
712        /// above.
713        ///
714        /// For cross-version compatibility use [`FunctionDefinition::kind()`].
715        kind: Option<FunctionKind>,
716        /// The state mutability of the function.
717        ///
718        /// Note: This was introduced in Solidity 0.5.x. For cross-version compatibility use
719        /// [`FunctionDefinition::state_mutability()`].
720        #[serde(default)]
721        state_mutability: Option<StateMutability>,
722        #[serde(default, rename = "virtual")]
723        is_virtual: bool,
724        /// Whether or not this function is the constructor. Only valid for Solidity versions below
725        /// 0.5.x.
726        ///
727        /// After 0.5.x you must use `kind`. For cross-version compatibility use
728        /// [`FunctionDefinition::kind()`].
729        #[serde(default)]
730        is_constructor: bool,
731        /// Whether or not this function is constant (view or pure). Only valid for Solidity
732        /// versions below 0.5.x.
733        ///
734        /// After 0.5.x you must use `state_mutability`. For cross-version compatibility use
735        /// [`FunctionDefinition::state_mutability()`].
736        #[serde(default)]
737        is_declared_const: bool,
738        /// Whether or not this function is payable. Only valid for Solidity versions below
739        /// 0.5.x.
740        ///
741        /// After 0.5.x you must use `state_mutability`. For cross-version compatibility use
742        /// [`FunctionDefinition::state_mutability()`].
743        #[serde(default)]
744        is_payable: bool,
745    }
746);
747
748impl FunctionDefinition {
749    /// The kind of function this node defines.
750    pub fn kind(&self) -> &FunctionKind {
751        if let Some(kind) = &self.kind {
752            kind
753        } else if self.is_constructor {
754            &FunctionKind::Constructor
755        } else {
756            &FunctionKind::Function
757        }
758    }
759
760    /// The state mutability of the function.
761    ///
762    /// Note: Before Solidity 0.5.x, this is an approximation, as there was no distinction between
763    /// `view` and `pure`.
764    pub fn state_mutability(&self) -> &StateMutability {
765        if let Some(state_mutability) = &self.state_mutability {
766            state_mutability
767        } else if self.is_declared_const {
768            &StateMutability::View
769        } else if self.is_payable {
770            &StateMutability::Payable
771        } else {
772            &StateMutability::Nonpayable
773        }
774    }
775}
776
777/// Function kinds.
778#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
779#[serde(rename_all = "camelCase")]
780pub enum FunctionKind {
781    /// A contract function.
782    Function,
783    /// A receive function.
784    Receive,
785    /// A constructor.
786    Constructor,
787    /// A fallback function.
788    Fallback,
789    /// A free-standing function.
790    FreeFunction,
791}
792
793ast_node!(
794    /// A block of statements.
795    struct Block {
796        documentation: Option<String>,
797        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
798        statements: Vec<Statement>,
799    }
800);
801
802stmt_node!(
803    /// The break keyword.
804    struct Break {}
805);
806
807stmt_node!(
808    /// The continue keyword.
809    struct Continue {}
810);
811
812stmt_node!(
813    /// A do while statement.
814    struct DoWhileStatement {
815        block: Block,
816        condition: Expression,
817    }
818);
819
820stmt_node!(
821    /// An emit statement.
822    struct EmitStatement {
823        event_call: FunctionCall,
824    }
825);
826
827stmt_node!(
828    /// An expression statement.
829    struct ExpressionStatement {
830        expression: Expression,
831    }
832);
833
834stmt_node!(
835    /// A for statement.
836    struct ForStatement {
837        body: BlockOrStatement,
838        condition: Option<Expression>,
839        initialization_expression: Option<ExpressionOrVariableDeclarationStatement>,
840        loop_expression: Option<ExpressionStatement>,
841    }
842);
843
844stmt_node!(
845    /// A variable declaration statement.
846    struct VariableDeclarationStatement {
847        assignments: Vec<Option<usize>>,
848        declarations: Vec<Option<VariableDeclaration>>,
849        initial_value: Option<Expression>,
850    }
851);
852
853stmt_node!(
854    /// An if statement.
855    struct IfStatement {
856        condition: Expression,
857        false_body: Option<BlockOrStatement>,
858        true_body: BlockOrStatement,
859    }
860);
861
862ast_node!(
863    /// A block of inline assembly.
864    ///
865    /// Refer to the [yul] module for Yul AST nodes.
866    struct InlineAssembly {
867        documentation: Option<String>,
868        #[serde(rename = "AST")]
869        ast: YulBlock,
870        // TODO: We need this camel case for the AST, but pascal case other places in ethers-solc
871        //evm_version: EvmVersion,
872        external_references: Vec<ExternalInlineAssemblyReference>,
873        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
874        flags: Vec<InlineAssemblyFlag>,
875    }
876);
877
878/// A reference to an external variable or slot in an inline assembly block.
879#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
880#[serde(rename_all = "camelCase")]
881pub struct ExternalInlineAssemblyReference {
882    #[serde(with = "serde_helpers::display_from_str")]
883    pub src: SourceLocation,
884    pub declaration: usize,
885    #[serde(default)]
886    pub offset: bool,
887    #[serde(default)]
888    pub slot: bool,
889    #[serde(default)]
890    pub length: bool,
891    pub value_size: usize,
892    pub suffix: Option<AssemblyReferenceSuffix>,
893}
894
895/// An assembly reference suffix.
896#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
897#[serde(rename_all = "camelCase")]
898pub enum AssemblyReferenceSuffix {
899    /// The reference refers to a storage slot.
900    Slot,
901    /// The reference refers to an offset.
902    Offset,
903    /// The reference refers to a length.
904    Length,
905}
906
907/// Inline assembly flags.
908#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
909pub enum InlineAssemblyFlag {
910    MemorySafe,
911}
912
913stmt_node!(
914    /// A placeholder statement (`_`)
915    struct PlaceholderStatement {}
916);
917
918stmt_node!(
919    /// A return statement.
920    struct Return {
921        expression: Option<Expression>,
922        function_return_parameters: usize,
923    }
924);
925
926stmt_node!(
927    /// A revert statement.
928    struct RevertStatement {
929        error_call: FunctionCall,
930    }
931);
932
933stmt_node!(
934    /// A try/catch statement.
935    struct TryStatement {
936        clauses: Vec<TryCatchClause>,
937        external_call: FunctionCall,
938    }
939);
940
941ast_node!(
942    /// A try/catch clause.
943    struct TryCatchClause {
944        block: Block,
945        error_name: String,
946        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
947        parameters: Vec<ParameterList>,
948    }
949);
950
951stmt_node!(
952    /// An unchecked block.
953    struct UncheckedBlock {
954        statements: Vec<Statement>,
955    }
956);
957
958stmt_node!(
959    /// A while statement.
960    struct WhileStatement {
961        body: BlockOrStatement,
962        condition: Expression,
963    }
964);
965
966ast_node!(
967    /// A modifier or base constructor invocation.
968    struct ModifierInvocation {
969        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
970        arguments: Vec<Expression>,
971        kind: Option<ModifierInvocationKind>,
972        modifier_name: IdentifierOrIdentifierPath,
973    }
974);
975
976/// Modifier invocation kinds.
977#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
978#[serde(rename_all = "camelCase")]
979pub enum ModifierInvocationKind {
980    /// A regular modifier invocation.
981    ModifierInvocation,
982    /// A base constructor invocation.
983    BaseConstructorSpecifier,
984}
985
986ast_node!(
987    /// A modifier definition.
988    struct ModifierDefinition {
989        name: String,
990        #[serde(default, with = "serde_helpers::display_from_str_opt")]
991        name_location: Option<SourceLocation>,
992        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
993        base_modifiers: Vec<usize>,
994        body: Block,
995        documentation: Option<StructuredDocumentation>,
996        overrides: Option<OverrideSpecifier>,
997        parameters: ParameterList,
998        #[serde(default, rename = "virtual")]
999        is_virtual: bool,
1000        visibility: Visibility,
1001    }
1002);
1003
1004ast_node!(
1005    /// A struct definition.
1006    struct StructDefinition {
1007        name: String,
1008        #[serde(default, with = "serde_helpers::display_from_str_opt")]
1009        name_location: Option<SourceLocation>,
1010        canonical_name: String,
1011        members: Vec<VariableDeclaration>,
1012        scope: usize,
1013        visibility: Visibility,
1014    }
1015);
1016
1017ast_node!(
1018    /// A user defined value type definition.
1019    struct UserDefinedValueTypeDefinition {
1020        name: String,
1021        #[serde(default, with = "serde_helpers::display_from_str_opt")]
1022        name_location: Option<SourceLocation>,
1023        canonical_name: Option<String>,
1024        underlying_type: TypeName,
1025    }
1026);
1027
1028ast_node!(
1029    /// A using for directive.
1030    struct UsingForDirective {
1031        #[serde(default, deserialize_with = "serde_helpers::default_for_null")]
1032        function_list: Vec<FunctionIdentifierPath>,
1033        #[serde(default)]
1034        global: bool,
1035        library_name: Option<UserDefinedTypeNameOrIdentifierPath>,
1036        type_name: Option<TypeName>,
1037    }
1038);
1039
1040/// A wrapper around [IdentifierPath] for the [UsingForDirective].
1041#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1042pub struct FunctionIdentifierPath {
1043    pub function: IdentifierPath,
1044}
1045
1046ast_node!(
1047    /// An import directive.
1048    struct ImportDirective {
1049        absolute_path: String,
1050        file: String,
1051        #[serde(default, with = "serde_helpers::display_from_str_opt")]
1052        name_location: Option<SourceLocation>,
1053        scope: usize,
1054        source_unit: usize,
1055        symbol_aliases: Vec<SymbolAlias>,
1056        unit_alias: String,
1057    }
1058);
1059
1060/// A symbol alias.
1061///
1062/// Symbol aliases can be defined using the [ImportDirective].
1063#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1064pub struct SymbolAlias {
1065    pub foreign: Identifier,
1066    pub local: Option<String>,
1067    #[serde(default, with = "serde_helpers::display_from_str_opt")]
1068    pub name_location: Option<SourceLocation>,
1069}
1070
1071ast_node!(
1072    /// A pragma directive.
1073    struct PragmaDirective {
1074        literals: Vec<String>,
1075    }
1076);
1077
1078#[cfg(test)]
1079mod tests {
1080    use super::*;
1081    use std::{fs, path::PathBuf};
1082
1083    #[test]
1084    fn can_parse_ast() {
1085        fs::read_dir(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test-data").join("ast"))
1086            .unwrap()
1087            .for_each(|path| {
1088                let path = path.unwrap().path();
1089                let path_str = path.to_string_lossy();
1090
1091                let input = fs::read_to_string(&path).unwrap();
1092                let deserializer = &mut serde_json::Deserializer::from_str(&input);
1093                let result: Result<SourceUnit, _> = serde_path_to_error::deserialize(deserializer);
1094                match result {
1095                    Err(e) => {
1096                        println!("... {path_str} fail: {e}");
1097                        panic!();
1098                    }
1099                    Ok(_) => {
1100                        println!("... {path_str} ok");
1101                    }
1102                }
1103            })
1104    }
1105}