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}