1mod macros;
16mod misc;
17pub use misc::*;
18pub mod utils;
19pub mod visitor;
20
21pub(crate) mod lowfidelity;
23pub use lowfidelity::{Ast, Node, NodeType, SourceLocation as LowFidelitySourceLocation};
24
25pub 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    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
132node_group! {
134    UserDefinedTypeNameOrIdentifierPath;
135
136    UserDefinedTypeName,
137    IdentifierPath,
138}
139
140#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
142#[serde(untagged)]
143pub enum BlockOrStatement {
144    Statement(Statement),
145    Block(Block),
146}
147
148node_group! {
150    ExpressionOrVariableDeclarationStatement;
151
152    ExpressionStatement,
153    VariableDeclarationStatement
154}
155
156node_group! {
158    IdentifierOrIdentifierPath;
159
160    Identifier,
161    IdentifierPath
162}
163
164ast_node!(
165    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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
193#[serde(rename_all = "camelCase")]
194pub enum ContractKind {
195    Contract,
197    Interface,
199    Library,
201}
202
203ast_node!(
204    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    struct Assignment {
215        #[serde(rename = "leftHandSide")]
216        lhs: Expression,
217        operator: AssignmentOperator,
218        #[serde(rename = "rightHandSide")]
219        rhs: Expression,
220    }
221);
222
223#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
225pub enum AssignmentOperator {
226    #[serde(rename = "=")]
228    Assign,
229    #[serde(rename = "+=")]
231    AddAssign,
232    #[serde(rename = "-=")]
234    SubAssign,
235    #[serde(rename = "*=")]
237    MulAssign,
238    #[serde(rename = "/=")]
240    DivAssign,
241    #[serde(rename = "%=")]
243    ModAssign,
244    #[serde(rename = "|=")]
246    OrAssign,
247    #[serde(rename = "&=")]
249    AndAssign,
250    #[serde(rename = "^=")]
252    XorAssign,
253    #[serde(rename = ">>=")]
255    ShrAssign,
256    #[serde(rename = "<<=")]
258    ShlAssign,
259}
260
261expr_node!(
262    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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
275pub enum BinaryOperator {
276    #[serde(rename = "+")]
278    Add,
279    #[serde(rename = "-")]
281    Sub,
282    #[serde(rename = "*")]
284    Mul,
285    #[serde(rename = "/")]
287    Div,
288    #[serde(rename = "%")]
290    Mod,
291    #[serde(rename = "**")]
293    Pow,
294    #[serde(rename = "&&")]
296    And,
297    #[serde(rename = "||")]
299    Or,
300    #[serde(rename = "!=")]
302    NotEqual,
303    #[serde(rename = "==")]
305    Equal,
306    #[serde(rename = "<")]
308    LessThan,
309    #[serde(rename = "<=")]
311    LessThanOrEqual,
312    #[serde(rename = ">")]
314    GreaterThan,
315    #[serde(rename = ">=")]
317    GreaterThanOrEqual,
318    #[serde(rename = "^")]
320    Xor,
321    #[serde(rename = "~")]
323    BitNot,
324    #[serde(rename = "&")]
326    BitAnd,
327    #[serde(rename = "|")]
329    BitOr,
330    #[serde(rename = "<<")]
332    Shl,
333    #[serde(rename = ">>")]
335    Shr,
336}
337
338expr_node!(
339    struct Conditional {
341        condition: Expression,
343        false_expression: Expression,
345        true_expression: Expression,
347    }
348);
349
350expr_node!(
351    struct ElementaryTypeNameExpression {
352        type_name: ElementaryOrRawTypeName,
353    }
354);
355
356#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
358#[serde(untagged)]
359pub enum ElementaryOrRawTypeName {
360    ElementaryTypeName(ElementaryTypeName),
364    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    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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
392#[serde(rename_all = "camelCase")]
393pub enum FunctionCallKind {
394    FunctionCall,
396    TypeConversion,
398    StructConstructorCall,
400}
401
402expr_node!(
403    struct FunctionCallOptions {
405        expression: Expression,
406        names: Vec<String>,
407        options: Vec<Expression>,
408    }
409);
410
411ast_node!(
412    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    struct IndexAccess {
426        base_expression: Expression,
427        index_expression: Option<Expression>,
428    }
429);
430
431expr_node!(
432    struct IndexRangeAccess {
434        base_expression: Expression,
435        start_expression: Option<Expression>,
436        end_expression: Option<Expression>,
437    }
438);
439
440expr_node!(
441    struct Literal {
443        hex_value: String,
445        kind: LiteralKind,
446        subdenomination: Option<String>, value: Option<String>,           }
449);
450
451#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
453#[serde(rename_all = "camelCase")]
454pub enum LiteralKind {
455    Bool,
457    Number,
459    String,
461    HexString,
463    UnicodeString,
465}
466
467expr_node!(
468    struct MemberAccess {
470        expression: Expression,
471        member_name: String,
472        referenced_declaration: Option<isize>,
473    }
474);
475
476expr_node!(
477    struct NewExpression {
479        type_name: TypeName,
480    }
481);
482
483ast_node!(
484    struct ArrayTypeName {
486        type_descriptions: TypeDescriptions,
487        base_type: TypeName,
488        length: Option<Expression>,
489    }
490);
491
492ast_node!(
493    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    struct ParameterList {
506        parameters: Vec<VariableDeclaration>,
507    }
508);
509
510ast_node!(
511    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        #[serde(default)]
523        constant: bool,
524        #[serde(default)]
529        state_variable: bool,
530        documentation: Option<Documentation>,
531        function_selector: Option<String>, #[serde(default)]
533        indexed: bool,
534        #[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    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    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    struct OverrideSpecifier {
582        overrides: Vec<UserDefinedTypeNameOrIdentifierPath>,
583    }
584);
585
586ast_node!(
587    struct UserDefinedTypeName {
589        type_descriptions: TypeDescriptions,
590        contract_scope: Option<String>, name: Option<String>,
592        path_node: Option<IdentifierPath>,
593        referenced_declaration: isize,
594    }
595);
596
597ast_node!(
598    struct IdentifierPath {
600        name: String,
601        referenced_declaration: isize,
602    }
603);
604
605ast_node!(
606    struct Mapping {
608        type_descriptions: TypeDescriptions,
609        key_type: TypeName,
610        value_type: TypeName,
611    }
612);
613
614expr_node!(
615    struct TupleExpression {
617        components: Vec<Option<Expression>>,
618        is_inline_array: bool,
619    }
620);
621
622expr_node!(
623    struct UnaryOperation {
625        operator: UnaryOperator,
626        prefix: bool,
628        sub_expression: Expression,
629    }
630);
631
632#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
634pub enum UnaryOperator {
635    #[serde(rename = "++")]
637    Increment,
638    #[serde(rename = "--")]
640    Decrement,
641    #[serde(rename = "-")]
643    Negate,
644    #[serde(rename = "!")]
646    Not,
647    #[serde(rename = "~")]
649    BitNot,
650    #[serde(rename = "delete")]
652    Delete,
653}
654
655ast_node!(
656    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    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    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>, parameters: ParameterList,
684    }
685);
686
687ast_node!(
688    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>, documentation: Option<Documentation>,
696        parameters: ParameterList,
697    }
698);
699
700ast_node!(
701    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>, implemented: bool,
712        modifiers: Vec<ModifierInvocation>,
713        overrides: Option<OverrideSpecifier>,
714        parameters: ParameterList,
715        return_parameters: ParameterList,
716        scope: usize,
717        visibility: Visibility,
718        kind: Option<FunctionKind>,
723        #[serde(default)]
728        state_mutability: Option<StateMutability>,
729        #[serde(default, rename = "virtual")]
730        is_virtual: bool,
731        #[serde(default)]
737        is_constructor: bool,
738        #[serde(default)]
744        is_declared_const: bool,
745        #[serde(default)]
751        is_payable: bool,
752    }
753);
754
755impl FunctionDefinition {
756    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    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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
786#[serde(rename_all = "camelCase")]
787pub enum FunctionKind {
788    Function,
790    Receive,
792    Constructor,
794    Fallback,
796    FreeFunction,
798}
799
800ast_node!(
801    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    struct Break {}
812);
813
814stmt_node!(
815    struct Continue {}
817);
818
819stmt_node!(
820    struct DoWhileStatement {
822        body: Block,
823        condition: Expression,
824    }
825);
826
827stmt_node!(
828    struct EmitStatement {
830        event_call: FunctionCall,
831    }
832);
833
834stmt_node!(
835    struct ExpressionStatement {
837        expression: Expression,
838    }
839);
840
841stmt_node!(
842    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    struct VariableDeclarationStatement {
854        assignments: Vec<Option<usize>>,
855        declarations: Vec<Option<VariableDeclaration>>,
856        initial_value: Option<Expression>,
857    }
858);
859
860stmt_node!(
861    struct IfStatement {
863        condition: Expression,
864        false_body: Option<BlockOrStatement>,
865        true_body: BlockOrStatement,
866    }
867);
868
869ast_node!(
870    struct InlineAssembly {
874        documentation: Option<String>,
875        #[serde(rename = "AST")]
876        ast: Option<YulBlock>,
877        operations: Option<String>,
878        #[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#[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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
906#[serde(rename_all = "camelCase")]
907pub enum AssemblyReferenceSuffix {
908    Slot,
910    Offset,
912    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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
928pub enum InlineAssemblyFlag {
929    #[serde(rename = "memory-safe")]
930    MemorySafe,
931}
932
933stmt_node!(
934    struct PlaceholderStatement {}
936);
937
938stmt_node!(
939    struct Return {
941        expression: Option<Expression>,
942        function_return_parameters: Option<usize>,
943    }
944);
945
946stmt_node!(
947    struct RevertStatement {
949        error_call: FunctionCall,
950    }
951);
952
953stmt_node!(
954    struct TryStatement {
956        clauses: Vec<TryCatchClause>,
957        external_call: FunctionCall,
958    }
959);
960
961ast_node!(
962    struct TryCatchClause {
964        block: Block,
965        error_name: String,
966        parameters: Option<ParameterList>,
967    }
968);
969
970stmt_node!(
971    struct UncheckedBlock {
973        statements: Vec<Statement>,
974    }
975);
976
977stmt_node!(
978    struct WhileStatement {
980        body: BlockOrStatement,
981        condition: Expression,
982    }
983);
984
985ast_node!(
986    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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
997#[serde(rename_all = "camelCase")]
998pub enum ModifierInvocationKind {
999    ModifierInvocation,
1001    BaseConstructorSpecifier,
1003}
1004
1005ast_node!(
1006    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    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    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    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#[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    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#[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    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}