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}