1use lalrpop_util::lalrpop_mod;
2
3lalrpop_mod!(#[allow(clippy::all, dead_code, unused_imports)] pub aidl);
4
5#[cfg(test)]
6#[allow(clippy::single_element_loop)]
7mod tests {
8    use crate::rules;
9    use anyhow::Result;
10
11    fn lookup(input: &str) -> line_col::LineColLookup {
12        line_col::LineColLookup::new(input)
13    }
14
15    macro_rules! assert_parser {
17        ($input:ident, $parser:expr) => {
18            let mut diagnostics = Vec::new();
19            let lookup = lookup($input);
20            let res = $parser.parse(&lookup, &mut diagnostics, $input)?;
21            ::insta::assert_ron_snapshot!(res, {
22                ".**.symbol_range" => "...",
23                ".**.full_range" => "...",
24                ".**.transact_code_range" => "...",
25                ".**.oneway_range" => "...",
26            });
27            assert_eq!(diagnostics, &[]);
28        };
29
30        ($input:ident, $parser:expr, $diag:expr) => {
31            let lookup = lookup($input);
32            let res = $parser.parse(&lookup, $diag, $input)?;
33            ::insta::assert_ron_snapshot!(res, {
34                ".**.symbol_range" => "...",
35                ".**.full_range" => "...",
36                ".**.transact_code_range" => "...",
37                ".**.oneway_range" => "...",
38            });
39        };
40    }
41
42    macro_rules! assert_diagnostics {
43        ($diag:expr, @$snapshot:literal) => {
44            ::insta::assert_ron_snapshot!($diag, {
45                ".**.range" => "...",
46            }, @$snapshot);
47        };
48    }
49
50    #[test]
51    fn test_aidl() -> Result<()> {
52        let input = r#"package x.y.z;
53            import a.b.c;
54            interface MyInterface {}
55        "#;
56        assert_parser!(input, rules::aidl::OptAidlParser::new());
57
58        Ok(())
59    }
60
61    #[test]
62    fn test_aidl_with_unrecovered_error() -> Result<()> {
63        use crate::diagnostic::ParseError;
64
65        let input = "wrong, wrong and wrong!";
66        let lookup = lookup(input);
67        let res = rules::aidl::OptAidlParser::new().parse(&lookup, &mut Vec::new(), input);
68
69        assert!(matches!(res, Err(ParseError::InvalidToken { .. })));
70
71        Ok(())
72    }
73
74    #[test]
75    fn test_aidl_with_recovered_error() -> Result<()> {
76        let input = r#"package x.y.z;
77               import a.b.c;
78               oops_interface MyInterface {}
79           "#;
80        let mut diagnostics = Vec::new();
81        assert_parser!(input, rules::aidl::OptAidlParser::new(), &mut diagnostics);
82
83        assert_diagnostics!(diagnostics, @r###"
84        [
85          Diagnostic(
86            kind: Error,
87            range: "...",
88            message: "Invalid item - Unrecognized token `oops_interface`.\nExpected one of ANNOTATION, ENUM, IMPORT, INTERFACE or PARCELABLE",
89            context_message: Some("unrecognized token"),
90            hint: None,
91            related_infos: [],
92          ),
93        ]
94        "###);
95
96        Ok(())
97    }
98
99    #[test]
100    fn test_package1() -> Result<()> {
101        let input = "package x ;";
102        assert_parser!(input, rules::aidl::PackageParser::new());
103
104        Ok(())
105    }
106
107    #[test]
108    fn test_package2() -> Result<()> {
109        let input = "package x.y.z;";
110        assert_parser!(input, rules::aidl::PackageParser::new());
111
112        Ok(())
113    }
114
115    #[test]
116    fn test_import() -> Result<()> {
117        let input = "import x.y.z;";
118        assert_parser!(input, rules::aidl::ImportParser::new());
119
120        Ok(())
121    }
122
123    #[test]
124    fn test_declared_parcelable() -> Result<()> {
125        let mut diagnostics = Vec::new();
126
127        let input = "parcelable X;";
128        assert_parser!(
129            input,
130            rules::aidl::DeclaredParcelableParser::new(),
131            &mut diagnostics
132        );
133        let input = "parcelable any.pkg.Y;";
134        assert_parser!(
135            input,
136            rules::aidl::DeclaredParcelableParser::new(),
137            &mut diagnostics
138        );
139        let input = "@Annotation1 @Annotation2\nparcelable any.pkg.Y;";
140        assert_parser!(
141            input,
142            rules::aidl::DeclaredParcelableParser::new(),
143            &mut diagnostics
144        );
145
146        Ok(())
147    }
148
149    #[test]
150    fn test_interface() -> Result<()> {
151        let input = r#"interface Potato {
152            /**
153             * const1 documentation
154             */
155            const int const1 = 1;
156    
157            /**
158             * method1 documentation
159             */
160            String method1();
161    
162            const String const2 = "two";
163            int method2();
164        }"#;
165        assert_parser!(input, rules::aidl::InterfaceParser::new());
166
167        Ok(())
168    }
169
170    #[test]
171    fn test_oneway_interface() -> Result<()> {
172        let input = r#"oneway interface OneWayInterface {}"#;
173        assert_parser!(input, rules::aidl::InterfaceParser::new());
174
175        Ok(())
176    }
177
178    #[test]
179    fn test_interface_with_annotation() -> Result<()> {
180        let input = r#"@InterfaceAnnotation1
181            @InterfaceAnnotation2 interface Potato {
182            }"#;
183        assert_parser!(input, rules::aidl::InterfaceParser::new());
184
185        Ok(())
186    }
187
188    #[test]
189    fn test_interface_with_javadoc() -> Result<()> {
190        let input = r#"
191            /** Documentation before */
192            /** Interface documentation */
193            /* Comment after */
194            // Line comment after
195            interface Potato {
196            }"#;
197        assert_parser!(input, rules::aidl::InterfaceParser::new());
198
199        Ok(())
200    }
201
202    #[test]
203    fn test_interface_with_errors() -> Result<()> {
204        let input = r#"interface Potato {
205            String method1();
206            int method2();
207            int oops_not_a_valid_method;
208            const String const2 = 123;
209            const oops_not_a_valid_const;
210        }"#;
211        let mut diagnostics = Vec::new();
212        assert_parser!(input, rules::aidl::InterfaceParser::new(), &mut diagnostics);
213
214        assert_diagnostics!(diagnostics, @r###"
215        [
216          Diagnostic(
217            kind: Error,
218            range: "...",
219            message: "Invalid interface element - Unrecognized token `;`.\nExpected \"(\"",
220            context_message: Some("unrecognized token"),
221            hint: None,
222            related_infos: [],
223          ),
224          Diagnostic(
225            kind: Error,
226            range: "...",
227            message: "Invalid interface element - Unrecognized token `;`.\nExpected one of \")\", \",\", \".\", \">\" or IDENT",
228            context_message: Some("unrecognized token"),
229            hint: None,
230            related_infos: [],
231          ),
232        ]
233        "###);
234
235        Ok(())
236    }
237
238    #[test]
239    fn test_parcelable() -> Result<()> {
240        let input = r#"parcelable Tomato {
241            /**
242             * const1 documentation
243             */
244            const int const1 = 1;
245
246            const int const2 = MyEnum.ELEMENT3;
247
248            /**
249             * field1 documentation
250             */
251            int field1;
252    
253            String field2; // inline comment
254        }"#;
255        assert_parser!(input, rules::aidl::ParcelableParser::new());
256
257        Ok(())
258    }
259
260    #[test]
261    fn test_parcelable_with_javadoc() -> Result<()> {
262        let input = r#"
263            /** Parcelable documentation */
264            parcelable Tomato {}"#;
265        assert_parser!(input, rules::aidl::ParcelableParser::new());
266
267        Ok(())
268    }
269
270    #[test]
271    fn test_parcelable_with_errors() -> Result<()> {
272        let input = r#"parcelable Tomato {
273            int field1;
274            wrongfield3;
275            String field3;
276        }"#;
277        let mut diagnostics = Vec::new();
278        assert_parser!(
279            input,
280            rules::aidl::ParcelableParser::new(),
281            &mut diagnostics
282        );
283        assert_diagnostics!(diagnostics, @r###"
284        [
285          Diagnostic(
286            kind: Error,
287            range: "...",
288            message: "Invalid parcelable element - Unrecognized token `;`.\nExpected one of \",\", \".\", \">\" or IDENT",
289            context_message: Some("unrecognized token"),
290            hint: None,
291            related_infos: [],
292          ),
293        ]
294        "###);
295
296        Ok(())
297    }
298
299    #[test]
300    fn test_enum() -> Result<()> {
301        let input = r#"enum Paprika {
302                /**
303                 * element1 documentation
304                 */
305                ELEMENT1 = 3,
306    
307                ELEMENT2 = "quattro",
308                ELEMENT3
309            }"#;
310        assert_parser!(input, rules::aidl::EnumParser::new());
311
312        Ok(())
313    }
314
315    #[test]
316    fn test_enum_with_javadoc() -> Result<()> {
317        let input = r#"
318            /** Enum documentation */
319            enum Tomato {
320                /** ELEMENT1 documentation */
321                ELEMENT1,
322                ELEMENT2,
323                /** ELEMENT3 documentation */
324                ELEMENT3,
325            }"#;
326        assert_parser!(input, rules::aidl::EnumParser::new());
327
328        Ok(())
329    }
330
331    #[test]
332    fn test_enum_with_errors() -> Result<()> {
333        let input = r#"enum Paprika {
334                ELEMENT1 = 3,
335                ELEMENT2 == "quattro",
336                ELEMENT3,
337                0843
338            }"#;
339        let mut diagnostics = Vec::new();
340        assert_parser!(input, rules::aidl::EnumParser::new(), &mut diagnostics);
341        assert_diagnostics!(diagnostics, @r###"
342        [
343          Diagnostic(
344            kind: Error,
345            range: "...",
346            message: "Invalid enum element - Unrecognized token `=`.\nExpected one of BOOLEAN, FLOAT or QUOTED_STRING",
347            context_message: Some("unrecognized token"),
348            hint: None,
349            related_infos: [],
350          ),
351          Diagnostic(
352            kind: Error,
353            range: "...",
354            message: "Invalid enum element - Unrecognized token `0843`.\nExpected one of \"}\" or IDENT",
355            context_message: Some("unrecognized token"),
356            hint: None,
357            related_infos: [],
358          ),
359        ]
360        "###);
361
362        Ok(())
363    }
364
365    #[test]
366    fn test_enum_with_trailing_comma() -> Result<()> {
367        let input = r#"enum Paprika {
368                ELEMENT1,
369                ELEMENT2,
370            }"#;
371        assert_parser!(input, rules::aidl::EnumParser::new());
372
373        Ok(())
374    }
375
376    #[test]
377    fn test_method_without_arg() -> Result<()> {
378        let input = "TypeName myMethod() ;";
379        assert_parser!(input, rules::aidl::MethodParser::new());
380
381        Ok(())
382    }
383
384    #[test]
385    fn test_method_with_1_arg() -> Result<()> {
386        let input = "TypeName myMethod(ArgType arg) ;";
387        assert_parser!(input, rules::aidl::MethodParser::new());
388
389        Ok(())
390    }
391
392    #[test]
393    fn test_method_with_3_args() -> Result<()> {
394        let input = "TypeName myMethod(ArgType1, ArgType2 arg2, ArgType3) ;";
395        assert_parser!(input, rules::aidl::MethodParser::new());
396
397        Ok(())
398    }
399
400    #[test]
401    fn test_method_oneway() -> Result<()> {
402        let input = "oneway TypeName myMethod();";
403        assert_parser!(input, rules::aidl::MethodParser::new());
404
405        Ok(())
406    }
407
408    #[test]
409    fn test_method_with_transact_code() -> Result<()> {
410        let input = "TypeName myMethod() = 123;";
411        assert_parser!(input, rules::aidl::MethodParser::new());
412
413        Ok(())
414    }
415
416    #[test]
417    fn test_method_with_invalid_transact_code() -> Result<()> {
418        let input = "TypeName myMethod() = 12.3;";
419        assert!(rules::aidl::MethodParser::new()
420            .parse(&lookup(input), &mut Vec::new(), input)
421            .is_err());
422
423        Ok(())
424    }
425
426    #[test]
427    fn test_method_with_annotation() -> Result<()> {
428        let input = "@AnnotationName void myMethod();";
429        assert_parser!(input, rules::aidl::MethodParser::new());
430
431        Ok(())
432    }
433
434    #[test]
435    fn test_method_with_javadoc() -> Result<()> {
436        let input = "/** Method documentation */ void myMethod() = 123;";
437        assert_parser!(input, rules::aidl::MethodParser::new());
438
439        Ok(())
440    }
441
442    #[test]
443    fn test_method_arg_with_name() -> Result<()> {
444        let input = "TypeName albert";
445        assert_parser!(input, rules::aidl::ArgParser::new());
446
447        Ok(())
448    }
449
450    #[test]
451    fn test_method_arg_with_direction() -> Result<()> {
452        let input = "in TypeName";
453        assert_parser!(input, rules::aidl::ArgParser::new());
454
455        Ok(())
456    }
457
458    #[test]
459    fn test_method_arg_with_direction_and_name() -> Result<()> {
460        let input = "out TypeName roger";
461        assert_parser!(input, rules::aidl::ArgParser::new());
462
463        Ok(())
464    }
465
466    #[test]
467    fn test_method_arg_with_annotations() -> Result<()> {
468        let input = r#"@Annotation1
469            @Annotation2(AnnotationParam ) TypeName albert"#;
470        assert_parser!(input, rules::aidl::ArgParser::new());
471
472        Ok(())
473    }
474
475    #[test]
476    fn test_method_arg_with_javadoc() -> Result<()> {
477        let input = "/** Arg documentation */ TypeName albert";
478        assert_parser!(input, rules::aidl::ArgParser::new());
479
480        Ok(())
481    }
482
483    #[test]
484    fn test_field() -> Result<()> {
485        let input = "TypeName fieldName ;";
486        assert_parser!(input, rules::aidl::FieldParser::new());
487        Ok(())
488    }
489
490    #[test]
491    fn test_field_with_value() -> Result<()> {
492        let input = "TypeName fieldName = \"field value\";";
493        assert_parser!(input, rules::aidl::FieldParser::new());
494
495        Ok(())
496    }
497
498    #[test]
499    fn test_field_with_javadoc() -> Result<()> {
500        let input = r#"/**
501             * Field documentation
502             */
503            TypeName fieldName;"#;
504        assert_parser!(input, rules::aidl::FieldParser::new());
505
506        Ok(())
507    }
508
509    #[test]
510    fn test_field_with_annotation() -> Result<()> {
511        let input = "@AnnotationName TypeName fieldName = \"field value\";";
512        assert_parser!(input, rules::aidl::FieldParser::new());
513
514        Ok(())
515    }
516
517    #[test]
518    fn test_const_num() -> Result<()> {
519        let input = "const int CONST_NAME = 123 ;";
520        assert_parser!(input, rules::aidl::ConstParser::new());
521
522        Ok(())
523    }
524
525    #[test]
526    fn test_const_string() -> Result<()> {
527        let input = "const TypeName CONST_NAME = \"const value\";";
528        assert_parser!(input, rules::aidl::ConstParser::new());
529
530        Ok(())
531    }
532
533    #[test]
534    fn test_const_with_javadoc() -> Result<()> {
535        let input = r#"/**
536            * Const documentation
537            */
538           const TypeName CONST_NAME = 123;"#;
539        assert_parser!(input, rules::aidl::ConstParser::new());
540
541        Ok(())
542    }
543
544    #[test]
545    fn test_const_with_annotation() -> Result<()> {
546        let input = "@AnnotationName const TypeName CONST_NAME = 123;";
547        assert_parser!(input, rules::aidl::ConstParser::new());
548
549        Ok(())
550    }
551
552    #[test]
553    fn test_type_primitive1() -> Result<()> {
554        let input = "double";
555        assert_parser!(input, rules::aidl::TypeParser::new());
556
557        Ok(())
558    }
559
560    #[test]
561    fn test_type_primitive2() -> Result<()> {
562        let input = "doublegum";
563        assert_parser!(input, rules::aidl::TypeParser::new());
564
565        Ok(())
566    }
567
568    #[test]
569    fn test_type_string() -> Result<()> {
570        let input = "String";
571        assert_parser!(input, rules::aidl::TypeParser::new());
572
573        Ok(())
574    }
575
576    #[test]
577    fn test_type_char_sequence() -> Result<()> {
578        let input = "CharSequence";
579        assert_parser!(input, rules::aidl::TypeParser::new());
580
581        Ok(())
582    }
583
584    #[test]
585    fn test_type_custom() -> Result<()> {
586        let input = "TypeName";
587        assert_parser!(input, rules::aidl::TypeParser::new());
588
589        Ok(())
590    }
591
592    #[test]
593    fn test_type_custom_with_namespace() -> Result<()> {
594        let input = "com.example.TypeName";
595        assert_parser!(input, rules::aidl::TypeParser::new());
596
597        Ok(())
598    }
599
600    #[test]
601    fn test_type_array() -> Result<()> {
602        let input = "float []";
603        assert_parser!(input, rules::aidl::TypeParser::new());
604
605        Ok(())
606    }
607
608    #[test]
609    fn test_type_array_bidirectional() -> Result<()> {
610        let input = "int [] []";
611        assert_parser!(input, rules::aidl::TypeParser::new());
612
613        Ok(())
614    }
615
616    #[test]
617    fn test_type_list() -> Result<()> {
618        let input = "List <MyObject >";
619        assert_parser!(input, rules::aidl::TypeParser::new());
620
621        Ok(())
622    }
623
624    #[test]
625    fn test_type_list_non_generic() -> Result<()> {
626        let input = "List";
627        assert_parser!(input, rules::aidl::TypeParser::new());
628
629        Ok(())
630    }
631
632    #[test]
633    fn test_type_list_invalid() -> Result<()> {
634        let input = "List<A, B>";
635        assert!(rules::aidl::ValueParser::new()
636            .parse(&lookup(input), &mut Vec::new(), input)
637            .is_err());
638
639        Ok(())
640    }
641
642    #[test]
643    fn test_type_map() -> Result<()> {
644        let input = "Map<Key,List<V>>";
645        assert_parser!(input, rules::aidl::TypeParser::new());
646
647        Ok(())
648    }
649
650    #[test]
651    fn test_type_map_non_generic() -> Result<()> {
652        let input = "Map";
653        assert_parser!(input, rules::aidl::TypeParser::new());
654
655        Ok(())
656    }
657
658    #[test]
659    fn test_type_map_invalid() -> Result<()> {
660        let input = "Map<A>";
661        assert!(rules::aidl::ValueParser::new()
662            .parse(&lookup(input), &mut Vec::new(), input)
663            .is_err());
664
665        let input = "Map<A,B,C>";
666        assert!(rules::aidl::ValueParser::new()
667            .parse(&lookup(input), &mut Vec::new(), input)
668            .is_err());
669
670        Ok(())
671    }
672
673    #[test]
674    fn test_value() -> Result<()> {
675        for input in ["12", "-12", "-0.12", "-.12", "-.12f"].into_iter() {
677            assert_eq!(
678                rules::aidl::ValueParser::new().parse(&lookup(input), &mut Vec::new(), input)?,
679                input
680            );
681        }
682
683        for input in ["-.", "--12", "0..2", "0.2y"].into_iter() {
685            assert!(rules::aidl::ValueParser::new()
686                .parse(&lookup(input), &mut Vec::new(), input)
687                .is_err());
688        }
689
690        for input in ["\"hello\"", "\"\"", "\"\t\""].into_iter() {
692            assert_eq!(
693                rules::aidl::ValueParser::new().parse(&lookup(input), &mut Vec::new(), input)?,
694                input
695            );
696        }
697
698        {
700            let input = "\"\"\"";
701            assert!(rules::aidl::ValueParser::new()
702                .parse(&lookup(input), &mut Vec::new(), input)
703                .is_err());
704        }
705
706        for input in ["{}", "{ }", "{      }"].into_iter() {
708            assert_eq!(
709                rules::aidl::ValueParser::new().parse(&lookup(input), &mut Vec::new(), input)?,
710                "{}"
711            );
712        }
713
714        for input in ["{\"hello{<\"}", "{1}", "{1, 2}", "{1, 2, 3, }"].into_iter() {
716            assert_eq!(
717                rules::aidl::ValueParser::new().parse(&lookup(input), &mut Vec::new(), input)?,
718                "{...}"
719            );
720        }
721
722        for input in ["MyEnum.WOOF"].into_iter() {
724            assert_eq!(
725                rules::aidl::ValueParser::new().parse(&lookup(input), &mut Vec::new(), input)?,
726                "MyEnum.WOOF"
727            );
728        }
729
730        for input in ["MyEnum", "{\"hello{<\"", "{1sfewf}", "{1, 2, 3,, }"].into_iter() {
732            assert!(rules::aidl::ValueParser::new()
733                .parse(&lookup(input), &mut Vec::new(), input)
734                .is_err());
735        }
736
737        Ok(())
738    }
739
740    #[test]
741    fn test_annotation1() -> Result<()> {
742        let input = "@AnnotationName";
743        assert_parser!(input, rules::aidl::OptAnnotationParser::new());
744
745        Ok(())
746    }
747
748    #[test]
749    fn test_annotation2() -> Result<()> {
750        let input = "@AnnotationName()";
751        assert_parser!(input, rules::aidl::OptAnnotationParser::new());
752
753        Ok(())
754    }
755
756    #[test]
757    fn test_annotation3() -> Result<()> {
758        let input = "@AnnotationName( Hello)";
759        assert_parser!(input, rules::aidl::OptAnnotationParser::new());
760
761        Ok(())
762    }
763
764    #[test]
765    fn test_annotation4() -> Result<()> {
766        let input = "@AnnotationName(Hello=\"World\")";
767        assert_parser!(input, rules::aidl::OptAnnotationParser::new());
768
769        Ok(())
770    }
771
772    #[test]
773    fn test_annotation5() -> Result<()> {
774        let mut settings = insta::Settings::clone_current();
775        settings.set_sort_maps(true);
776        let _guard = settings.bind_to_scope();
777
778        let input = "@AnnotationName(Hello=\"World\", Hi, Servus= 3 )";
779        assert_parser!(input, rules::aidl::OptAnnotationParser::new());
780
781        Ok(())
782    }
783
784    #[test]
785    fn test_reserved_keywords() -> Result<()> {
786        let input = "package a.for.b;";
787        assert!(rules::aidl::PackageParser::new()
788            .parse(&lookup(input), &mut Vec::new(), input)
789            .is_err());
790
791        Ok(())
792    }
793}