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