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: Option<bool>,
180 #[serde(default)]
182 linearized_base_contracts: Vec<usize>,
183 nodes: Vec<ContractDefinitionPart>,
184 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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
197#[serde(rename_all = "camelCase")]
198pub enum ContractKind {
199 Contract,
201 Interface,
203 Library,
205}
206
207ast_node!(
208 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 struct Assignment {
219 #[serde(rename = "leftHandSide")]
220 lhs: Expression,
221 operator: AssignmentOperator,
222 #[serde(rename = "rightHandSide")]
223 rhs: Expression,
224 }
225);
226
227#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
229pub enum AssignmentOperator {
230 #[serde(rename = "=")]
232 Assign,
233 #[serde(rename = "+=")]
235 AddAssign,
236 #[serde(rename = "-=")]
238 SubAssign,
239 #[serde(rename = "*=")]
241 MulAssign,
242 #[serde(rename = "/=")]
244 DivAssign,
245 #[serde(rename = "%=")]
247 ModAssign,
248 #[serde(rename = "|=")]
250 OrAssign,
251 #[serde(rename = "&=")]
253 AndAssign,
254 #[serde(rename = "^=")]
256 XorAssign,
257 #[serde(rename = ">>=")]
259 ShrAssign,
260 #[serde(rename = "<<=")]
262 ShlAssign,
263}
264
265expr_node!(
266 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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
279pub enum BinaryOperator {
280 #[serde(rename = "+")]
282 Add,
283 #[serde(rename = "-")]
285 Sub,
286 #[serde(rename = "*")]
288 Mul,
289 #[serde(rename = "/")]
291 Div,
292 #[serde(rename = "%")]
294 Mod,
295 #[serde(rename = "**")]
297 Pow,
298 #[serde(rename = "&&")]
300 And,
301 #[serde(rename = "||")]
303 Or,
304 #[serde(rename = "!=")]
306 NotEqual,
307 #[serde(rename = "==")]
309 Equal,
310 #[serde(rename = "<")]
312 LessThan,
313 #[serde(rename = "<=")]
315 LessThanOrEqual,
316 #[serde(rename = ">")]
318 GreaterThan,
319 #[serde(rename = ">=")]
321 GreaterThanOrEqual,
322 #[serde(rename = "^")]
324 Xor,
325 #[serde(rename = "~")]
327 BitNot,
328 #[serde(rename = "&")]
330 BitAnd,
331 #[serde(rename = "|")]
333 BitOr,
334 #[serde(rename = "<<")]
336 Shl,
337 #[serde(rename = ">>")]
339 Shr,
340}
341
342expr_node!(
343 struct Conditional {
345 condition: Expression,
347 false_expression: Expression,
349 true_expression: Expression,
351 }
352);
353
354expr_node!(
355 struct ElementaryTypeNameExpression {
356 type_name: ElementaryOrRawTypeName,
357 }
358);
359
360#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
362#[serde(untagged)]
363pub enum ElementaryOrRawTypeName {
364 ElementaryTypeName(ElementaryTypeName),
368 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 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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
396#[serde(rename_all = "camelCase")]
397pub enum FunctionCallKind {
398 FunctionCall,
400 TypeConversion,
402 StructConstructorCall,
404}
405
406expr_node!(
407 struct FunctionCallOptions {
409 expression: Expression,
410 names: Vec<String>,
411 options: Vec<Expression>,
412 }
413);
414
415ast_node!(
416 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 struct IndexAccess {
430 base_expression: Expression,
431 index_expression: Option<Expression>,
432 }
433);
434
435expr_node!(
436 struct IndexRangeAccess {
438 base_expression: Expression,
439 start_expression: Option<Expression>,
440 end_expression: Option<Expression>,
441 }
442);
443
444expr_node!(
445 struct Literal {
447 hex_value: String,
449 kind: LiteralKind,
450 subdenomination: Option<String>, value: Option<String>, }
453);
454
455#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
457#[serde(rename_all = "camelCase")]
458pub enum LiteralKind {
459 Bool,
461 Number,
463 String,
465 HexString,
467 UnicodeString,
469}
470
471expr_node!(
472 struct MemberAccess {
474 expression: Expression,
475 member_name: String,
476 referenced_declaration: Option<isize>,
477 }
478);
479
480expr_node!(
481 struct NewExpression {
483 type_name: TypeName,
484 }
485);
486
487ast_node!(
488 struct ArrayTypeName {
490 type_descriptions: TypeDescriptions,
491 base_type: TypeName,
492 length: Option<Expression>,
493 }
494);
495
496ast_node!(
497 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 struct ParameterList {
510 parameters: Vec<VariableDeclaration>,
511 }
512);
513
514ast_node!(
515 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 #[serde(default)]
527 constant: bool,
528 #[serde(default)]
533 state_variable: bool,
534 documentation: Option<Documentation>,
535 function_selector: Option<String>, #[serde(default)]
537 indexed: bool,
538 #[serde(default)]
541 mutability: Option<Mutability>,
542 overrides: Option<OverrideSpecifier>,
543 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 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 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 struct OverrideSpecifier {
587 overrides: Vec<UserDefinedTypeNameOrIdentifierPath>,
588 }
589);
590
591ast_node!(
592 struct UserDefinedTypeName {
594 type_descriptions: TypeDescriptions,
595 contract_scope: Option<String>, name: Option<String>,
597 path_node: Option<IdentifierPath>,
598 referenced_declaration: isize,
599 }
600);
601
602ast_node!(
603 struct IdentifierPath {
605 name: String,
606 referenced_declaration: isize,
607 }
608);
609
610ast_node!(
611 struct Mapping {
613 type_descriptions: TypeDescriptions,
614 key_type: TypeName,
615 value_type: TypeName,
616 }
617);
618
619expr_node!(
620 struct TupleExpression {
622 components: Vec<Option<Expression>>,
623 is_inline_array: bool,
624 }
625);
626
627expr_node!(
628 struct UnaryOperation {
630 operator: UnaryOperator,
631 prefix: bool,
633 sub_expression: Expression,
634 }
635);
636
637#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
639pub enum UnaryOperator {
640 #[serde(rename = "++")]
642 Increment,
643 #[serde(rename = "--")]
645 Decrement,
646 #[serde(rename = "-")]
648 Negate,
649 #[serde(rename = "!")]
651 Not,
652 #[serde(rename = "~")]
654 BitNot,
655 #[serde(rename = "delete")]
657 Delete,
658}
659
660ast_node!(
661 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 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 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>, parameters: ParameterList,
689 }
690);
691
692ast_node!(
693 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>, documentation: Option<Documentation>,
701 parameters: ParameterList,
702 }
703);
704
705ast_node!(
706 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>, implemented: bool,
717 modifiers: Vec<ModifierInvocation>,
718 overrides: Option<OverrideSpecifier>,
719 parameters: ParameterList,
720 return_parameters: ParameterList,
721 scope: Option<usize>,
723 visibility: Visibility,
724 kind: Option<FunctionKind>,
729 #[serde(default)]
734 state_mutability: Option<StateMutability>,
735 #[serde(default, rename = "virtual")]
736 is_virtual: bool,
737 #[serde(default)]
743 is_constructor: bool,
744 #[serde(default)]
750 is_declared_const: bool,
751 #[serde(default)]
757 is_payable: bool,
758 }
759);
760
761impl FunctionDefinition {
762 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 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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
792#[serde(rename_all = "camelCase")]
793pub enum FunctionKind {
794 Function,
796 Receive,
798 Constructor,
800 Fallback,
802 FreeFunction,
804}
805
806ast_node!(
807 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 struct Break {}
818);
819
820stmt_node!(
821 struct Continue {}
823);
824
825stmt_node!(
826 struct DoWhileStatement {
828 body: Block,
829 condition: Expression,
830 }
831);
832
833stmt_node!(
834 struct EmitStatement {
836 event_call: FunctionCall,
837 }
838);
839
840stmt_node!(
841 struct ExpressionStatement {
843 expression: Expression,
844 }
845);
846
847stmt_node!(
848 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 struct VariableDeclarationStatement {
860 assignments: Vec<Option<usize>>,
861 declarations: Vec<Option<VariableDeclaration>>,
862 initial_value: Option<Expression>,
863 }
864);
865
866stmt_node!(
867 struct IfStatement {
869 condition: Expression,
870 false_body: Option<BlockOrStatement>,
871 true_body: BlockOrStatement,
872 }
873);
874
875ast_node!(
876 struct InlineAssembly {
880 documentation: Option<String>,
881 #[serde(rename = "AST")]
882 ast: Option<YulBlock>,
883 operations: Option<String>,
884 #[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#[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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
912#[serde(rename_all = "camelCase")]
913pub enum AssemblyReferenceSuffix {
914 Slot,
916 Offset,
918 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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
934pub enum InlineAssemblyFlag {
935 #[serde(rename = "memory-safe")]
936 MemorySafe,
937}
938
939stmt_node!(
940 struct PlaceholderStatement {}
942);
943
944stmt_node!(
945 struct Return {
947 expression: Option<Expression>,
948 function_return_parameters: Option<usize>,
949 }
950);
951
952stmt_node!(
953 struct RevertStatement {
955 error_call: FunctionCall,
956 }
957);
958
959stmt_node!(
960 struct TryStatement {
962 clauses: Vec<TryCatchClause>,
963 external_call: FunctionCall,
964 }
965);
966
967ast_node!(
968 struct TryCatchClause {
970 block: Block,
971 error_name: String,
972 parameters: Option<ParameterList>,
973 }
974);
975
976stmt_node!(
977 struct UncheckedBlock {
979 statements: Vec<Statement>,
980 }
981);
982
983stmt_node!(
984 struct WhileStatement {
986 body: BlockOrStatement,
987 condition: Expression,
988 }
989);
990
991ast_node!(
992 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#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
1003#[serde(rename_all = "camelCase")]
1004pub enum ModifierInvocationKind {
1005 ModifierInvocation,
1007 BaseConstructorSpecifier,
1009}
1010
1011ast_node!(
1012 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 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 scope: Option<usize>,
1039 visibility: Visibility,
1040 }
1041);
1042
1043ast_node!(
1044 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 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#[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 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 scope: Option<usize>,
1094 source_unit: usize,
1095 symbol_aliases: Vec<SymbolAlias>,
1096 unit_alias: String,
1097 }
1098);
1099
1100#[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 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}