collect_macros.rs 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. //! Collect macros from a file
  2. //!
  3. //! Returns all macros that match a pattern. You can use this information to autoformat them later
  4. use proc_macro2::LineColumn;
  5. use syn::{visit::Visit, File, Macro};
  6. type CollectedMacro<'a> = &'a Macro;
  7. pub fn collect_from_file<'a, 'b>(file: &'a File, macros: &'b mut Vec<CollectedMacro<'a>>) {
  8. MacroCollector::visit_file(&mut MacroCollector { macros }, file);
  9. }
  10. struct MacroCollector<'a, 'b> {
  11. macros: &'a mut Vec<CollectedMacro<'b>>,
  12. }
  13. impl<'a, 'b> Visit<'b> for MacroCollector<'a, 'b> {
  14. fn visit_macro(&mut self, i: &'b Macro) {
  15. self.macros.push(i);
  16. }
  17. }
  18. pub fn byte_offset(input: &str, location: LineColumn) -> usize {
  19. let mut offset = 0;
  20. for _ in 1..location.line {
  21. offset += input[offset..].find('\n').unwrap() + 1;
  22. }
  23. offset
  24. + input[offset..]
  25. .chars()
  26. .take(location.column)
  27. .map(char::len_utf8)
  28. .sum::<usize>()
  29. }
  30. #[test]
  31. fn parses_file_and_collects_rsx_macros() {
  32. let contents = include_str!("../tests/samples/long.rsx");
  33. let parsed = syn::parse_file(contents).unwrap();
  34. let mut macros = vec![];
  35. collect_from_file(&parsed, &mut macros);
  36. assert_eq!(macros.len(), 3);
  37. }