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