1#![doc = include_str!("../README.md")]
2
3#[cfg(feature = "find")]
4mod find;
5#[cfg(feature = "find")]
6pub use find::Find;
7
8use std::{
9 any::{self, Any, TypeId},
10 cell::{Cell, RefCell, RefMut},
11 cmp,
12 collections::HashMap,
13 ops,
14 pin::Pin,
15 sync::{LazyLock, Mutex, MutexGuard, OnceLock},
16};
17
18type Result<T> = std::result::Result<T, Error>;
19type Error = Box<dyn std::error::Error + Send + Sync>;
20
21static LOCATOR: LazyLock<Mutex<Locator>> = LazyLock::new(|| Mutex::new(Locator::new()));
23
24thread_local! {
25 static EN_TL_LOCATOR: Cell<bool> = const { Cell::new(false) };
26
27 static TL_LOCATOR: RefCell<Locator> = RefCell::new(Locator::new());
29}
30
31pub fn enable_thread_local(en: bool) {
32 EN_TL_LOCATOR.replace(en);
33}
34
35pub fn is_located(file_path: &str) -> bool {
36 if EN_TL_LOCATOR.get() {
37 TL_LOCATOR.with(|locator| locator.borrow().contains_file(file_path))
38 } else {
39 LOCATOR.lock().unwrap().contains_file(file_path)
40 }
41}
42
43pub fn clear() {
45 if EN_TL_LOCATOR.get() {
46 TL_LOCATOR.with_borrow_mut(|locator| locator.clear());
47 } else {
48 let mut locator = LOCATOR.lock().unwrap();
49 locator.clear();
50 }
51}
52
53pub enum LocatorGuard<'a> {
54 Mutex(MutexGuard<'a, Locator>),
55 RefMut(RefMut<'a, Locator>),
56}
57
58impl<'a> ops::Deref for LocatorGuard<'a> {
59 type Target = Locator;
60
61 fn deref(&self) -> &Self::Target {
62 match self {
63 Self::Mutex(v) => v,
64 Self::RefMut(v) => v,
65 }
66 }
67}
68
69impl ops::DerefMut for LocatorGuard<'_> {
70 fn deref_mut(&mut self) -> &mut Self::Target {
71 match self {
72 Self::Mutex(v) => v,
73 Self::RefMut(v) => v,
74 }
75 }
76}
77
78pub trait LocateEntry: Locate {
79 fn locate_as_entry(self: Pin<&Self>, file_path: &str, code: &str) -> Result<()> {
80 let loc = self.location(file_path, code)?;
81
82 if EN_TL_LOCATOR.get() {
83 TL_LOCATOR.with(|locator| {
84 let mut locator = LocatorGuard::RefMut(locator.borrow_mut());
85 let Some(code) = locator.filtered_code_ptr(file_path) else {
86 drop(locator);
87 panic!("failed to find `{file_path}`");
88 };
89
90 unsafe {
93 let code = code.as_ref().unwrap_unchecked();
94 self.locate(&mut locator, loc.file_path, code, 0);
95 }
96 });
97 } else {
98 let mut locator = LocatorGuard::Mutex(LOCATOR.lock().unwrap());
99 let Some(code) = locator.filtered_code_ptr(file_path) else {
100 drop(locator);
101 panic!("failed to find `{file_path}`");
102 };
103
104 unsafe {
107 let code = code.as_ref().unwrap_unchecked();
108 self.locate(&mut locator, loc.file_path, code, 0);
109 }
110 }
111
112 Ok(())
113 }
114
115 #[doc(hidden)]
116 fn location(self: Pin<&Self>, file_path: &str, code: &str) -> Result<Location> {
117 let code: Box<str> = code.into();
118
119 if EN_TL_LOCATOR.get() {
120 TL_LOCATOR.with_borrow_mut(|locator| locator.insert_file(&*self, file_path, code))
121 } else {
122 LOCATOR.lock().unwrap().insert_file(&*self, file_path, code)
123 }
124 }
125}
126
127impl<T: Locate> LocateEntry for T {}
128
129pub trait Locate: Any {
130 fn find_loc(
141 &self,
142 locator: &mut LocatorGuard,
143 file_path: &'static str,
144 code: &str,
145 offset: usize,
146 ) -> Location;
147
148 fn relocate(&self, locator: &mut LocatorGuard, loc: Location) {
149 locator.set_location(self, loc);
150 }
151
152 fn locate(
154 &self,
155 locator: &mut LocatorGuard,
156 file_path: &'static str,
157 code: &str,
158 offset: usize,
159 ) -> Location {
160 let loc = self.find_loc(locator, file_path, code, offset);
161 locator.set_location(self, loc);
162 loc
163 }
164
165 fn location(&self) -> Location {
168 if EN_TL_LOCATOR.get() {
169 TL_LOCATOR
170 .with_borrow_mut(|locator| locator.get_location(self))
171 .unwrap_or_else(|| {
172 panic!(
173 "failed to find the location of `{}`. did you forget `Locate::locate`?",
174 any::type_name_of_val(self)
175 )
176 })
177 } else {
178 let locator = LOCATOR.lock().unwrap();
179 let Some(loc) = locator.get_location(self) else {
180 drop(locator);
181 panic!(
182 "failed to find the location of `{}`. did you forget `Locate::locate`?",
183 any::type_name_of_val(self)
184 )
185 };
186 loc
187 }
188 }
189
190 fn _location(&self, locator: &LocatorGuard) -> Location {
191 locator.get_location(self).unwrap_or_else(|| {
192 panic!(
193 "failed to find the location of `{}`. did you forget `Locate::locate`?",
194 any::type_name_of_val(self)
195 )
196 })
197 }
198
199 fn location_message(&self) -> String {
202 if EN_TL_LOCATOR.get() {
203 TL_LOCATOR
204 .with_borrow_mut(|locator| {
205 let loc = locator.get_location(self)?;
206 let path = loc.file_path;
207 let code = locator.get_original_code(path)?;
208 let line = code.as_bytes()[..loc.start]
209 .iter()
210 .filter(|&&b| b == b'\n')
211 .count()
212 + 1;
213 let content = &code[loc.start..loc.end];
214
215 Some(format!("{path}:{line}: {content}"))
216 })
217 .unwrap_or_else(|| {
218 panic!(
219 "failed to find the location of `{}`. did you forget `Locate::locate`?",
220 any::type_name_of_val(self)
221 )
222 })
223 } else {
224 let panic = || -> ! {
225 panic!(
226 "failed to find the location of `{}`. did you forget `Locate::locate`?",
227 any::type_name_of_val(self)
228 )
229 };
230
231 let locator = LOCATOR.lock().unwrap();
232
233 let Some(loc) = locator.get_location(self) else {
234 drop(locator);
235 panic();
236 };
237
238 let path = loc.file_path;
239 let Some(code) = locator.get_original_code(path) else {
240 drop(locator);
241 panic();
242 };
243
244 let line = code.as_bytes()[..loc.start]
245 .iter()
246 .filter(|&&b| b == b'\n')
247 .count()
248 + 1;
249
250 let content = &code[loc.start..loc.end];
251 format!("{path}:{line}: {content}")
252 }
253 }
254
255 fn code(&self) -> String {
258 if EN_TL_LOCATOR.get() {
259 TL_LOCATOR
260 .with_borrow_mut(|locator| {
261 let loc = locator.get_location(self)?;
262 let path = loc.file_path;
263 let code = locator.get_original_code(path)?;
264 let content = &code[loc.start..loc.end];
265
266 Some(content.to_owned())
267 })
268 .unwrap_or_else(|| {
269 panic!(
270 "failed to find the location of `{}`. did you forget `Locate::locate`?",
271 any::type_name_of_val(self)
272 )
273 })
274 } else {
275 let panic = || -> ! {
276 panic!(
277 "failed to find the location of `{}`. did you forget `Locate::locate`?",
278 any::type_name_of_val(self)
279 )
280 };
281
282 let locator = LOCATOR.lock().unwrap();
283
284 let Some(loc) = locator.get_location(self) else {
285 drop(locator);
286 panic();
287 };
288
289 let path = loc.file_path;
290 let Some(code) = locator.get_original_code(path) else {
291 drop(locator);
292 panic();
293 };
294
295 let content = &code[loc.start..loc.end];
296 content.to_owned()
297 }
298 }
299}
300
301pub trait LocateGroup {
302 fn locate_as_group(
303 &self,
304 locator: &mut LocatorGuard,
305 file_path: &'static str,
306 code: &str,
307 offset: usize,
308 ) -> Location;
309 fn relocate_as_group(&self, locator: &mut LocatorGuard, loc: Location);
310}
311
312macro_rules! impl_locate_group {
313 ( $($i:expr),* ; $($ri:expr),* ) => {
314 paste::paste! {
315 impl<'a, $([<A $i>]: Locate),*> LocateGroup for ( $( &'a [<A $i>] ),* ) {
316 #[allow(unused_assignments)]
317 fn locate_as_group(
318 &self,
319 locator: &mut LocatorGuard,
320 file_path: &'static str,
321 code: &str,
322 offset: usize
323 ) -> Location
324 {
325 let ( $( [<this $i>] ),* ) = self;
326
327 let mut end = offset;
329 $(
330 let [<loc $i>] = [<this $i>].locate(locator, file_path, code, end);
331 end = [<loc $i>].end;
332 )*
333
334 let mut start = usize::MAX;
336 $(
337 if [<loc $i>].start != [<loc $i>].end {
338 start = start.min( [<loc $i>].start );
339 }
340 )*
341 if start == usize::MAX {
342 start = offset;
343 }
344
345 let mut cur = end;
347 $(
348 if [<loc $ri>].start == [<loc $ri>].end {
349 [<this $ri>].relocate(locator, Location {
350 file_path,
351 start: cur,
352 end: cur
353 });
354 } else {
355 cur = [<loc $ri>].start;
356 }
357 )*
358
359 Location {
360 file_path,
361 start,
362 end
363 }
364 }
365
366 fn relocate_as_group(&self, locator: &mut LocatorGuard, loc: Location) {
367 let ( $( [<this $i>] ),* ) = self;
368
369 $(
371 [<this $i>].relocate(locator, loc);
372 )*
373 }
374 }
375 }
376 };
377}
378
379impl LocateGroup for () {
380 fn locate_as_group(
381 &self,
382 _: &mut LocatorGuard,
383 file_path: &'static str,
384 _code: &str,
385 offset: usize,
386 ) -> Location {
387 Location {
388 file_path,
389 start: offset,
390 end: offset,
391 }
392 }
393
394 fn relocate_as_group(&self, _: &mut LocatorGuard, _: Location) {}
395}
396
397impl<T: Locate> LocateGroup for &T {
398 fn locate_as_group(
399 &self,
400 locator: &mut LocatorGuard,
401 file_path: &'static str,
402 code: &str,
403 offset: usize,
404 ) -> Location {
405 self.locate(locator, file_path, code, offset)
406 }
407
408 fn relocate_as_group(&self, locator: &mut LocatorGuard, loc: Location) {
409 self.relocate(locator, loc)
410 }
411}
412
413impl_locate_group!(0, 1 ; 1, 0);
414impl_locate_group!(0, 1, 2 ; 2, 1, 0);
415impl_locate_group!(0, 1, 2, 3 ; 3, 2, 1, 0);
416impl_locate_group!(0, 1, 2, 3, 4 ; 4, 3, 2, 1, 0);
417impl_locate_group!(0, 1, 2, 3, 4, 5 ; 5, 4, 3, 2, 1, 0);
418impl_locate_group!(0, 1, 2, 3, 4, 5, 6 ; 6, 5, 4, 3, 2, 1, 0);
419impl_locate_group!(0, 1, 2, 3, 4, 5, 6, 7 ; 7, 6, 5, 4, 3, 2, 1, 0);
420impl_locate_group!(0, 1, 2, 3, 4, 5, 6, 7, 8 ; 8, 7, 6, 5, 4, 3, 2, 1, 0);
421impl_locate_group!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ; 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
422impl_locate_group!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ; 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
423impl_locate_group!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ; 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
424
425pub struct Surround<'s, F, S, I, B> {
426 pub front: F,
427 pub surround: &'s S,
428 pub inner: I,
429 pub back: B,
430}
431
432impl<F, S, I, B> Surround<'_, F, S, I, B>
433where
434 F: LocateGroup,
435 S: Locate,
436 I: LocateGroup,
437 B: LocateGroup,
438{
439 pub fn locate(
440 &self,
441 locator: &mut LocatorGuard,
442 file_path: &'static str,
443 code: &str,
444 offset: usize,
445 ) -> Location {
446 let front_loc = self.front.locate_as_group(locator, file_path, code, offset);
448 let surround_loc = self
449 .surround
450 .locate(locator, file_path, code, front_loc.end);
451 self.inner
452 .locate_as_group(locator, file_path, code, surround_loc.start + 1);
453 let back_loc = self
454 .back
455 .locate_as_group(locator, file_path, code, surround_loc.end);
456
457 let mut start = front_loc.start;
459 if front_loc.start == front_loc.end {
460 self.front.relocate_as_group(
461 locator,
462 Location {
463 file_path,
464 start: surround_loc.start,
465 end: surround_loc.start,
466 },
467 );
468 start = surround_loc.start;
469 }
470
471 let mut end = back_loc.end;
473 if back_loc.start == back_loc.end {
474 self.back.relocate_as_group(
475 locator,
476 Location {
477 file_path,
478 start: surround_loc.end,
479 end: surround_loc.end,
480 },
481 );
482 end = surround_loc.end;
483 }
484
485 Location {
486 file_path,
487 start,
488 end,
489 }
490 }
491}
492
493pub struct Qualified<'a, F, B> {
494 pub front: F,
495 pub qself: &'a syn::QSelf,
496 pub path: &'a syn::Path,
497 pub back: B,
498}
499
500impl<F, B> Qualified<'_, F, B>
501where
502 F: LocateGroup,
503 B: LocateGroup,
504{
505 pub fn locate(
506 &self,
507 locator: &mut LocatorGuard,
508 file_path: &'static str,
509 code: &str,
510 offset: usize,
511 ) -> Location {
512 let front_loc = self.front.locate_as_group(locator, file_path, code, offset);
514
515 let qself_loc = self.qself.locate(locator, file_path, code, front_loc.end);
516 let qself_mid_loc = self.qself.as_token._location(locator);
517
518 let path_loc = self
522 .path
523 .locate(locator, file_path, code, qself_mid_loc.end);
524
525 let back_loc = self
526 .back
527 .locate_as_group(locator, file_path, code, path_loc.end);
528
529 let mut start = front_loc.start;
531 if front_loc.start == front_loc.end {
532 self.front.relocate_as_group(
533 locator,
534 Location {
535 file_path,
536 start: qself_loc.start,
537 end: qself_loc.start,
538 },
539 );
540 start = qself_loc.start;
541 }
542
543 let mut end = back_loc.end;
545 if back_loc.start == back_loc.end {
546 self.back.relocate_as_group(
547 locator,
548 Location {
549 file_path,
550 start: path_loc.end,
551 end: path_loc.end,
552 },
553 );
554 end = path_loc.end;
555 }
556
557 Location {
558 file_path,
559 start,
560 end,
561 }
562 }
563}
564
565pub struct Locator {
566 files: HashMap<&'static str, Content>,
567 map: HashMap<LocationKey, Location>,
568}
569
570impl Locator {
571 fn new() -> Self {
572 Self {
573 files: HashMap::new(),
574 map: HashMap::new(),
575 }
576 }
577
578 fn clear(&mut self) {
579 for (file_path, _) in self.files.drain() {
580 let ptr = file_path as *const str as *mut str;
581 unsafe { drop(Box::from_raw(ptr)) };
582 }
583
584 self.map.clear();
585 }
586
587 fn contains_file(&self, file_path: &str) -> bool {
588 self.files.contains_key(file_path)
589 }
590
591 fn insert_file<T: Any + ?Sized>(
593 &mut self,
594 syn_file: &T,
595 file_path: &str,
596 code: Box<str>,
597 ) -> Result<Location> {
598 fn inner(
599 this: &mut Locator,
600 key: LocationKey,
601 file_path: &str,
602 code: Box<str>,
603 ) -> Result<Location> {
604 if let Some(loc) = this.map.get(&key) {
605 return Ok(*loc);
606 }
607 if this.contains_file(file_path) {
608 return Err(
609 format!("`syn-locator` detected duplicate file path: `{file_path}`").into(),
610 );
611 }
612
613 let file_path: Box<str> = file_path.into();
614 let file_path = Box::leak(file_path);
615 let loc = Location {
616 file_path,
617 start: 0,
618 end: code.len(),
619 };
620 this.files.insert(file_path, Content::new(code));
621 this.map.insert(key, loc);
622
623 Ok(loc)
624 }
625
626 inner(self, LocationKey::new(syn_file), file_path, code)
627 }
628
629 fn set_location<T: Any + ?Sized>(&mut self, syn_node: &T, loc: Location) {
630 self.map.insert(LocationKey::new(syn_node), loc);
631 }
632
633 fn get_location<T: Any + ?Sized>(&self, syn_node: &T) -> Option<Location> {
634 self.map.get(&LocationKey::new(syn_node)).cloned()
635 }
636
637 fn get_original_code(&self, file_path: &str) -> Option<&str> {
638 self.files
639 .get(file_path)
640 .map(|file| (*file.original_code).as_ref())
641 }
642
643 fn filtered_code_ptr(&self, file_path: &str) -> Option<*const str> {
644 self.files.get(file_path).map(|file| {
645 let code = &*file.filtered_code.as_ref();
646 code as *const _
647 })
648 }
649}
650
651impl Drop for Locator {
652 fn drop(&mut self) {
653 self.clear();
654 }
655}
656
657struct Content {
658 original_code: Pin<Box<str>>,
659 filtered_code: Pin<Box<str>>,
660}
661
662impl Content {
663 fn new(code: Box<str>) -> Self {
664 let filtered_code = Self::remove_non_tokens((*code).as_ref());
665 Self {
666 original_code: Pin::new(code),
667 filtered_code,
668 }
669 }
670
671 fn remove_non_tokens(code: &str) -> Pin<Box<str>> {
674 use regex::{Captures, Regex};
675
676 static RE: OnceLock<Regex> = OnceLock::new();
677
678 let re = RE.get_or_init(|| {
681 Regex::new(
682 r#"(?x)
683 (//[^\n]*) # Single line comment
684 |
685 (?s)
686 (/\*.*?\*/) # Block comment (Recursion is not supported)
687 "#,
688 )
689 .unwrap()
690 });
691
692 let s: Box<str> = re
693 .replace_all(code, |caps: &Captures| " ".repeat(caps[0].len()))
694 .into();
695 Box::into_pin(s)
696 }
697}
698
699#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
700struct LocationKey {
701 ptr: usize,
703
704 ty: TypeId,
707}
708
709impl LocationKey {
710 fn new<T: Any + ?Sized>(t: &T) -> Self {
711 Self {
712 ptr: t as *const T as *const () as usize,
713 ty: TypeId::of::<T>(),
714 }
715 }
716}
717
718#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
719pub struct Location {
720 pub file_path: &'static str,
721
722 pub start: usize,
724
725 pub end: usize,
727}
728
729impl PartialOrd for Location {
730 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
731 Some(self.cmp(other))
732 }
733}
734
735impl Ord for Location {
736 fn cmp(&self, other: &Self) -> cmp::Ordering {
737 match self.file_path.cmp(other.file_path) {
738 cmp::Ordering::Equal => match self.start.cmp(&other.start) {
739 cmp::Ordering::Equal => self.end.cmp(&other.end),
740 o => o,
741 },
742 o => o,
743 }
744 }
745}
746
747macro_rules! impl_locate_for_token {
748 ($ty:ty, $token:literal, char) => {
749 impl Locate for $ty {
750 fn find_loc(
751 &self,
752 _: &mut LocatorGuard,
753 file_path: &'static str,
754 code: &str,
755 offset: usize,
756 ) -> Location {
757 helper::char_location(file_path, code, offset, $token)
758 }
759 }
760 };
761 ($ty:ty, $token:literal, str) => {
762 impl Locate for $ty {
763 fn find_loc(
764 &self,
765 _: &mut LocatorGuard,
766 file_path: &'static str,
767 code: &str,
768 offset: usize,
769 ) -> Location {
770 helper::str_location(file_path, code, offset, $token)
771 }
772 }
773 };
774}
775
776impl_locate_for_token!(syn::Token![abstract], "abstract", str);
777impl_locate_for_token!(syn::Token![as], "as", str);
778impl_locate_for_token!(syn::Token![async], "async", str);
779impl_locate_for_token!(syn::Token![auto], "auto", str);
780impl_locate_for_token!(syn::Token![await], "await", str);
781impl_locate_for_token!(syn::Token![become], "become", str);
782impl_locate_for_token!(syn::Token![box], "box", str);
783impl_locate_for_token!(syn::Token![break], "break", str);
784impl_locate_for_token!(syn::Token![const], "const", str);
785impl_locate_for_token!(syn::Token![continue], "continue", str);
786impl_locate_for_token!(syn::Token![crate], "crate", str);
787impl_locate_for_token!(syn::Token![default], "default", str);
788impl_locate_for_token!(syn::Token![do], "do", str);
789impl_locate_for_token!(syn::Token![dyn], "dyn", str);
790impl_locate_for_token!(syn::Token![else], "else", str);
791impl_locate_for_token!(syn::Token![enum], "enum", str);
792impl_locate_for_token!(syn::Token![extern], "extern", str);
793impl_locate_for_token!(syn::Token![final], "final", str);
794impl_locate_for_token!(syn::Token![fn], "fn", str);
795impl_locate_for_token!(syn::Token![for], "for", str);
796impl_locate_for_token!(syn::Token![if], "if", str);
797impl_locate_for_token!(syn::Token![impl], "impl", str);
798impl_locate_for_token!(syn::Token![in], "in", str);
799impl_locate_for_token!(syn::Token![let], "let", str);
800impl_locate_for_token!(syn::Token![loop], "loop", str);
801impl_locate_for_token!(syn::Token![macro], "macro", str);
802impl_locate_for_token!(syn::Token![match], "match", str);
803impl_locate_for_token!(syn::Token![mod], "mod", str);
804impl_locate_for_token!(syn::Token![move], "move", str);
805impl_locate_for_token!(syn::Token![mut], "mut", str);
806impl_locate_for_token!(syn::Token![override], "override", str);
807impl_locate_for_token!(syn::Token![priv], "priv", str);
808impl_locate_for_token!(syn::Token![pub], "pub", str);
809impl_locate_for_token!(syn::Token![raw], "raw", str);
810impl_locate_for_token!(syn::Token![ref], "ref", str);
811impl_locate_for_token!(syn::Token![return], "return", str);
812impl_locate_for_token!(syn::Token![Self], "Self", str);
813impl_locate_for_token!(syn::Token![self], "self", str);
814impl_locate_for_token!(syn::Token![static], "static", str);
815impl_locate_for_token!(syn::Token![struct], "struct", str);
816impl_locate_for_token!(syn::Token![super], "super", str);
817impl_locate_for_token!(syn::Token![trait], "trait", str);
818impl_locate_for_token!(syn::Token![try], "try", str);
819impl_locate_for_token!(syn::Token![type], "type", str);
820impl_locate_for_token!(syn::Token![typeof], "typeof", str);
821impl_locate_for_token!(syn::Token![union], "union", str);
822impl_locate_for_token!(syn::Token![unsafe], "unsafe", str);
823impl_locate_for_token!(syn::Token![unsized], "unsized", str);
824impl_locate_for_token!(syn::Token![use], "use", str);
825impl_locate_for_token!(syn::Token![virtual], "virtual", str);
826impl_locate_for_token!(syn::Token![where], "where", str);
827impl_locate_for_token!(syn::Token![while], "while", str);
828impl_locate_for_token!(syn::Token![yield], "yield", str);
829impl_locate_for_token!(syn::Token![&], '&', char);
830impl_locate_for_token!(syn::Token![&&], "&&", str);
831impl_locate_for_token!(syn::Token![&=], "&=", str);
832impl_locate_for_token!(syn::Token![@], '@', char);
833impl_locate_for_token!(syn::Token![^], '^', char);
834impl_locate_for_token!(syn::Token![^=], "^=", str);
835impl_locate_for_token!(syn::Token![:], ':', char);
836impl_locate_for_token!(syn::Token![,], ',', char);
837impl_locate_for_token!(syn::Token![$], '$', char);
838impl_locate_for_token!(syn::Token![.], '.', char);
839impl_locate_for_token!(syn::Token![..], "..", str);
840impl_locate_for_token!(syn::Token![...], "...", str);
841impl_locate_for_token!(syn::Token![..=], "..=", str);
842impl_locate_for_token!(syn::Token![=], '=', char);
843impl_locate_for_token!(syn::Token![==], "==", str);
844impl_locate_for_token!(syn::Token![=>], "=>", str);
845impl_locate_for_token!(syn::Token![>=], ">=", str);
846impl_locate_for_token!(syn::Token![>], '>', char);
847impl_locate_for_token!(syn::Token![<-], "<-", str);
848impl_locate_for_token!(syn::Token![<=], "<=", str);
849impl_locate_for_token!(syn::Token![<], '<', char);
850impl_locate_for_token!(syn::Token![-], '-', char);
851impl_locate_for_token!(syn::Token![-=], "-=", str);
852impl_locate_for_token!(syn::Token![!=], "!=", str);
853impl_locate_for_token!(syn::Token![!], '!', char);
854impl_locate_for_token!(syn::Token![|], '|', char);
855impl_locate_for_token!(syn::Token![|=], "|=", str);
856impl_locate_for_token!(syn::Token![||], "||", str);
857impl_locate_for_token!(syn::Token![::], "::", str);
858impl_locate_for_token!(syn::Token![%], '%', char);
859impl_locate_for_token!(syn::Token![%=], "%=", str);
860impl_locate_for_token!(syn::Token![+], '+', char);
861impl_locate_for_token!(syn::Token![+=], "+=", str);
862impl_locate_for_token!(syn::Token![#], '#', char);
863impl_locate_for_token!(syn::Token![?], '?', char);
864impl_locate_for_token!(syn::Token![->], "->", str);
865impl_locate_for_token!(syn::Token![;], ';', char);
866impl_locate_for_token!(syn::Token![<<], "<<", str);
867impl_locate_for_token!(syn::Token![<<=], "<<=", str);
868impl_locate_for_token!(syn::Token![>>], ">>", str);
869impl_locate_for_token!(syn::Token![>>=], ">>=", str);
870impl_locate_for_token!(syn::Token![/], '/', char);
871impl_locate_for_token!(syn::Token![/=], "/=", str);
872impl_locate_for_token!(syn::Token![*], '*', char);
873impl_locate_for_token!(syn::Token![*=], "*=", str);
874impl_locate_for_token!(syn::Token![~], '~', char);
875impl_locate_for_token!(syn::Token![_], '_', char);
876
877impl Locate for syn::token::Group {
878 fn find_loc(
879 &self,
880 _: &mut LocatorGuard,
881 file_path: &'static str,
882 _code: &str,
883 offset: usize,
884 ) -> Location {
885 Location {
886 file_path,
887 start: offset,
888 end: offset,
889 }
890 }
891}
892
893macro_rules! impl_locate_for_pair_tokens {
894 ($ty:ty, $open:literal, $close:literal) => {
895 impl Locate for $ty {
896 fn find_loc(
897 &self,
898 _: &mut LocatorGuard,
899 file_path: &'static str,
900 code: &str,
901 offset: usize,
902 ) -> Location {
903 const OPEN: char = $open;
904 const CLOSE: char = $close;
905
906 let cur_code = &code[offset..];
907
908 let mut start = 0;
909 let mut end = 0;
910 let mut cur = offset;
911 let mut level = 0;
912
913 for c in cur_code.chars() {
914 if c == OPEN {
915 if level == 0 {
916 start = cur;
917 }
918 level += 1;
919 } else if c == CLOSE {
920 if level == 1 {
921 end = cur + CLOSE.len_utf8();
922 break;
923 }
924 if level > 0 {
925 level -= 1;
926 }
927 }
928 cur += c.len_utf8();
929 }
930
931 if start >= end {
932 panic!("expected `{OPEN}..{CLOSE}` from {cur_code}");
933 }
934
935 Location {
936 file_path,
937 start,
938 end,
939 }
940 }
941 }
942 };
943}
944
945impl_locate_for_pair_tokens!(syn::token::Brace, '{', '}');
946impl_locate_for_pair_tokens!(syn::token::Bracket, '[', ']');
947impl_locate_for_pair_tokens!(syn::token::Paren, '(', ')');
948
949impl Locate for syn::Abi {
950 fn find_loc(
951 &self,
952 locator: &mut LocatorGuard,
953 file_path: &'static str,
954 code: &str,
955 offset: usize,
956 ) -> Location {
957 (&self.extern_token, &self.name).locate_as_group(locator, file_path, code, offset)
958 }
959}
960
961impl Locate for syn::AngleBracketedGenericArguments {
962 fn find_loc(
963 &self,
964 locator: &mut LocatorGuard,
965 file_path: &'static str,
966 code: &str,
967 offset: usize,
968 ) -> Location {
969 (
970 &self.colon2_token,
971 &self.lt_token,
972 &self.args,
973 &self.gt_token,
974 )
975 .locate_as_group(locator, file_path, code, offset)
976 }
977}
978
979impl Locate for syn::Arm {
980 fn find_loc(
981 &self,
982 locator: &mut LocatorGuard,
983 file_path: &'static str,
984 code: &str,
985 offset: usize,
986 ) -> Location {
987 if let Some((if_token, guard)) = &self.guard {
988 (
989 &self.attrs,
990 &self.pat,
991 if_token,
992 guard,
993 &self.fat_arrow_token,
994 &self.body,
995 &self.comma,
996 )
997 .locate_as_group(locator, file_path, code, offset)
998 } else {
999 (
1000 &self.attrs,
1001 &self.pat,
1002 &self.fat_arrow_token,
1003 &self.body,
1004 &self.comma,
1005 )
1006 .locate_as_group(locator, file_path, code, offset)
1007 }
1008 }
1009}
1010
1011impl Locate for syn::AssocConst {
1012 fn find_loc(
1013 &self,
1014 locator: &mut LocatorGuard,
1015 file_path: &'static str,
1016 code: &str,
1017 offset: usize,
1018 ) -> Location {
1019 (&self.ident, &self.generics, &self.eq_token, &self.value)
1020 .locate_as_group(locator, file_path, code, offset)
1021 }
1022}
1023
1024impl Locate for syn::AssocType {
1025 fn find_loc(
1026 &self,
1027 locator: &mut LocatorGuard,
1028 file_path: &'static str,
1029 code: &str,
1030 offset: usize,
1031 ) -> Location {
1032 (&self.ident, &self.generics, &self.eq_token, &self.ty)
1033 .locate_as_group(locator, file_path, code, offset)
1034 }
1035}
1036
1037impl Locate for syn::Attribute {
1038 fn find_loc(
1039 &self,
1040 locator: &mut LocatorGuard,
1041 file_path: &'static str,
1042 code: &str,
1043 offset: usize,
1044 ) -> Location {
1045 Surround {
1046 front: (&self.pound_token, &self.style),
1047 surround: &self.bracket_token,
1048 inner: &self.meta,
1049 back: (),
1050 }
1051 .locate(locator, file_path, code, offset)
1052 }
1053}
1054
1055impl Locate for syn::AttrStyle {
1056 fn find_loc(
1057 &self,
1058 locator: &mut LocatorGuard,
1059 file_path: &'static str,
1060 code: &str,
1061 offset: usize,
1062 ) -> Location {
1063 match self {
1064 Self::Outer => Location {
1065 file_path,
1066 start: offset,
1067 end: offset,
1068 },
1069 Self::Inner(v) => v.find_loc(locator, file_path, code, offset),
1070 }
1071 }
1072}
1073
1074impl Locate for syn::BareFnArg {
1075 fn find_loc(
1076 &self,
1077 locator: &mut LocatorGuard,
1078 file_path: &'static str,
1079 code: &str,
1080 offset: usize,
1081 ) -> Location {
1082 if let Some((name, colon_token)) = &self.name {
1083 (&self.attrs, name, colon_token, &self.ty)
1084 .locate_as_group(locator, file_path, code, offset)
1085 } else {
1086 (&self.attrs, &self.ty).locate_as_group(locator, file_path, code, offset)
1087 }
1088 }
1089}
1090
1091impl Locate for syn::BareVariadic {
1092 fn find_loc(
1093 &self,
1094 locator: &mut LocatorGuard,
1095 file_path: &'static str,
1096 code: &str,
1097 offset: usize,
1098 ) -> Location {
1099 if let Some((name, colon_token)) = &self.name {
1100 (&self.attrs, name, colon_token, &self.dots, &self.comma)
1101 .locate_as_group(locator, file_path, code, offset)
1102 } else {
1103 (&self.attrs, &self.dots, &self.comma).locate_as_group(locator, file_path, code, offset)
1104 }
1105 }
1106}
1107
1108impl Locate for syn::BinOp {
1109 fn find_loc(
1110 &self,
1111 locator: &mut LocatorGuard,
1112 file_path: &'static str,
1113 code: &str,
1114 offset: usize,
1115 ) -> Location {
1116 match self {
1117 Self::Add(v) => v.locate(locator, file_path, code, offset),
1118 Self::Sub(v) => v.locate(locator, file_path, code, offset),
1119 Self::Mul(v) => v.locate(locator, file_path, code, offset),
1120 Self::Div(v) => v.locate(locator, file_path, code, offset),
1121 Self::Rem(v) => v.locate(locator, file_path, code, offset),
1122 Self::And(v) => v.locate(locator, file_path, code, offset),
1123 Self::Or(v) => v.locate(locator, file_path, code, offset),
1124 Self::BitXor(v) => v.locate(locator, file_path, code, offset),
1125 Self::BitAnd(v) => v.locate(locator, file_path, code, offset),
1126 Self::BitOr(v) => v.locate(locator, file_path, code, offset),
1127 Self::Shl(v) => v.locate(locator, file_path, code, offset),
1128 Self::Shr(v) => v.locate(locator, file_path, code, offset),
1129 Self::Eq(v) => v.locate(locator, file_path, code, offset),
1130 Self::Lt(v) => v.locate(locator, file_path, code, offset),
1131 Self::Le(v) => v.locate(locator, file_path, code, offset),
1132 Self::Ne(v) => v.locate(locator, file_path, code, offset),
1133 Self::Ge(v) => v.locate(locator, file_path, code, offset),
1134 Self::Gt(v) => v.locate(locator, file_path, code, offset),
1135 Self::AddAssign(v) => v.locate(locator, file_path, code, offset),
1136 Self::SubAssign(v) => v.locate(locator, file_path, code, offset),
1137 Self::MulAssign(v) => v.locate(locator, file_path, code, offset),
1138 Self::DivAssign(v) => v.locate(locator, file_path, code, offset),
1139 Self::RemAssign(v) => v.locate(locator, file_path, code, offset),
1140 Self::BitXorAssign(v) => v.locate(locator, file_path, code, offset),
1141 Self::BitAndAssign(v) => v.locate(locator, file_path, code, offset),
1142 Self::BitOrAssign(v) => v.locate(locator, file_path, code, offset),
1143 Self::ShlAssign(v) => v.locate(locator, file_path, code, offset),
1144 Self::ShrAssign(v) => v.locate(locator, file_path, code, offset),
1145 _ => Location {
1146 file_path,
1147 start: offset,
1148 end: offset,
1149 },
1150 }
1151 }
1152}
1153
1154impl Locate for syn::Block {
1155 fn find_loc(
1156 &self,
1157 locator: &mut LocatorGuard,
1158 file_path: &'static str,
1159 code: &str,
1160 offset: usize,
1161 ) -> Location {
1162 Surround {
1163 front: (),
1164 surround: &self.brace_token,
1165 inner: &self.stmts,
1166 back: (),
1167 }
1168 .locate(locator, file_path, code, offset)
1169 }
1170}
1171
1172impl Locate for syn::BoundLifetimes {
1173 fn find_loc(
1174 &self,
1175 locator: &mut LocatorGuard,
1176 file_path: &'static str,
1177 code: &str,
1178 offset: usize,
1179 ) -> Location {
1180 (
1181 &self.for_token,
1182 &self.lt_token,
1183 &self.lifetimes,
1184 &self.gt_token,
1185 )
1186 .locate_as_group(locator, file_path, code, offset)
1187 }
1188}
1189
1190impl Locate for syn::CapturedParam {
1191 fn find_loc(
1192 &self,
1193 locator: &mut LocatorGuard,
1194 file_path: &'static str,
1195 code: &str,
1196 offset: usize,
1197 ) -> Location {
1198 match self {
1199 Self::Lifetime(v) => v.locate(locator, file_path, code, offset),
1200 Self::Ident(v) => v.locate(locator, file_path, code, offset),
1201 _ => Location {
1202 file_path,
1203 start: offset,
1204 end: offset,
1205 },
1206 }
1207 }
1208}
1209
1210impl Locate for syn::ConstParam {
1211 fn find_loc(
1212 &self,
1213 locator: &mut LocatorGuard,
1214 file_path: &'static str,
1215 code: &str,
1216 offset: usize,
1217 ) -> Location {
1218 (
1219 &self.attrs,
1220 &self.const_token,
1221 &self.ident,
1222 &self.colon_token,
1223 &self.ty,
1224 &self.eq_token,
1225 &self.default,
1226 )
1227 .locate_as_group(locator, file_path, code, offset)
1228 }
1229}
1230
1231impl Locate for syn::Constraint {
1232 fn find_loc(
1233 &self,
1234 locator: &mut LocatorGuard,
1235 file_path: &'static str,
1236 code: &str,
1237 offset: usize,
1238 ) -> Location {
1239 (&self.ident, &self.generics, &self.colon_token, &self.bounds)
1240 .locate_as_group(locator, file_path, code, offset)
1241 }
1242}
1243
1244impl Locate for syn::Expr {
1245 fn find_loc(
1246 &self,
1247 locator: &mut LocatorGuard,
1248 file_path: &'static str,
1249 code: &str,
1250 offset: usize,
1251 ) -> Location {
1252 match self {
1253 Self::Array(v) => v.locate(locator, file_path, code, offset),
1254 Self::Assign(v) => v.locate(locator, file_path, code, offset),
1255 Self::Async(v) => v.locate(locator, file_path, code, offset),
1256 Self::Await(v) => v.locate(locator, file_path, code, offset),
1257 Self::Binary(v) => v.locate(locator, file_path, code, offset),
1258 Self::Block(v) => v.locate(locator, file_path, code, offset),
1259 Self::Break(v) => v.locate(locator, file_path, code, offset),
1260 Self::Call(v) => v.locate(locator, file_path, code, offset),
1261 Self::Cast(v) => v.locate(locator, file_path, code, offset),
1262 Self::Closure(v) => v.locate(locator, file_path, code, offset),
1263 Self::Const(v) => v.locate(locator, file_path, code, offset),
1264 Self::Continue(v) => v.locate(locator, file_path, code, offset),
1265 Self::Field(v) => v.locate(locator, file_path, code, offset),
1266 Self::ForLoop(v) => v.locate(locator, file_path, code, offset),
1267 Self::Group(v) => v.locate(locator, file_path, code, offset),
1268 Self::If(v) => v.locate(locator, file_path, code, offset),
1269 Self::Index(v) => v.locate(locator, file_path, code, offset),
1270 Self::Infer(v) => v.locate(locator, file_path, code, offset),
1271 Self::Let(v) => v.locate(locator, file_path, code, offset),
1272 Self::Lit(v) => v.locate(locator, file_path, code, offset),
1273 Self::Loop(v) => v.locate(locator, file_path, code, offset),
1274 Self::Macro(v) => v.locate(locator, file_path, code, offset),
1275 Self::Match(v) => v.locate(locator, file_path, code, offset),
1276 Self::MethodCall(v) => v.locate(locator, file_path, code, offset),
1277 Self::Paren(v) => v.locate(locator, file_path, code, offset),
1278 Self::Path(v) => v.locate(locator, file_path, code, offset),
1279 Self::Range(v) => v.locate(locator, file_path, code, offset),
1280 Self::RawAddr(v) => v.locate(locator, file_path, code, offset),
1281 Self::Reference(v) => v.locate(locator, file_path, code, offset),
1282 Self::Repeat(v) => v.locate(locator, file_path, code, offset),
1283 Self::Return(v) => v.locate(locator, file_path, code, offset),
1284 Self::Struct(v) => v.locate(locator, file_path, code, offset),
1285 Self::Try(v) => v.locate(locator, file_path, code, offset),
1286 Self::TryBlock(v) => v.locate(locator, file_path, code, offset),
1287 Self::Tuple(v) => v.locate(locator, file_path, code, offset),
1288 Self::Unary(v) => v.locate(locator, file_path, code, offset),
1289 Self::Unsafe(v) => v.locate(locator, file_path, code, offset),
1290 Self::Verbatim(_) => Location {
1291 file_path,
1292 start: offset,
1293 end: offset,
1294 },
1295 Self::While(v) => v.locate(locator, file_path, code, offset),
1296 Self::Yield(v) => v.locate(locator, file_path, code, offset),
1297 _ => Location {
1298 file_path,
1299 start: offset,
1300 end: offset,
1301 },
1302 }
1303 }
1304}
1305
1306impl Locate for syn::ExprArray {
1307 fn find_loc(
1308 &self,
1309 locator: &mut LocatorGuard,
1310 file_path: &'static str,
1311 code: &str,
1312 offset: usize,
1313 ) -> Location {
1314 Surround {
1315 front: &self.attrs,
1316 surround: &self.bracket_token,
1317 inner: &self.elems,
1318 back: (),
1319 }
1320 .locate(locator, file_path, code, offset)
1321 }
1322}
1323
1324impl Locate for syn::ExprAssign {
1325 fn find_loc(
1326 &self,
1327 locator: &mut LocatorGuard,
1328 file_path: &'static str,
1329 code: &str,
1330 offset: usize,
1331 ) -> Location {
1332 (&self.attrs, &self.left, &self.eq_token, &self.right)
1333 .locate_as_group(locator, file_path, code, offset)
1334 }
1335}
1336
1337impl Locate for syn::ExprAsync {
1338 fn find_loc(
1339 &self,
1340 locator: &mut LocatorGuard,
1341 file_path: &'static str,
1342 code: &str,
1343 offset: usize,
1344 ) -> Location {
1345 (&self.attrs, &self.async_token, &self.capture, &self.block)
1346 .locate_as_group(locator, file_path, code, offset)
1347 }
1348}
1349
1350impl Locate for syn::ExprAwait {
1351 fn find_loc(
1352 &self,
1353 locator: &mut LocatorGuard,
1354 file_path: &'static str,
1355 code: &str,
1356 offset: usize,
1357 ) -> Location {
1358 (&self.attrs, &self.base, &self.dot_token, &self.await_token)
1359 .locate_as_group(locator, file_path, code, offset)
1360 }
1361}
1362
1363impl Locate for syn::ExprBinary {
1364 fn find_loc(
1365 &self,
1366 locator: &mut LocatorGuard,
1367 file_path: &'static str,
1368 code: &str,
1369 offset: usize,
1370 ) -> Location {
1371 (&self.attrs, &self.left, &self.op, &self.right)
1372 .locate_as_group(locator, file_path, code, offset)
1373 }
1374}
1375
1376impl Locate for syn::ExprBlock {
1377 fn find_loc(
1378 &self,
1379 locator: &mut LocatorGuard,
1380 file_path: &'static str,
1381 code: &str,
1382 offset: usize,
1383 ) -> Location {
1384 (&self.attrs, &self.label, &self.block).locate_as_group(locator, file_path, code, offset)
1385 }
1386}
1387
1388impl Locate for syn::ExprBreak {
1389 fn find_loc(
1390 &self,
1391 locator: &mut LocatorGuard,
1392 file_path: &'static str,
1393 code: &str,
1394 offset: usize,
1395 ) -> Location {
1396 (&self.attrs, &self.break_token, &self.label, &self.expr)
1397 .locate_as_group(locator, file_path, code, offset)
1398 }
1399}
1400
1401impl Locate for syn::ExprCall {
1402 fn find_loc(
1403 &self,
1404 locator: &mut LocatorGuard,
1405 file_path: &'static str,
1406 code: &str,
1407 offset: usize,
1408 ) -> Location {
1409 Surround {
1410 front: (&self.attrs, &self.func),
1411 surround: &self.paren_token,
1412 inner: &self.args,
1413 back: (),
1414 }
1415 .locate(locator, file_path, code, offset)
1416 }
1417}
1418
1419impl Locate for syn::ExprCast {
1420 fn find_loc(
1421 &self,
1422 locator: &mut LocatorGuard,
1423 file_path: &'static str,
1424 code: &str,
1425 offset: usize,
1426 ) -> Location {
1427 (&self.attrs, &self.expr, &self.as_token, &self.ty)
1428 .locate_as_group(locator, file_path, code, offset)
1429 }
1430}
1431
1432impl Locate for syn::ExprClosure {
1433 fn find_loc(
1434 &self,
1435 locator: &mut LocatorGuard,
1436 file_path: &'static str,
1437 code: &str,
1438 offset: usize,
1439 ) -> Location {
1440 (
1441 &self.attrs,
1442 &self.lifetimes,
1443 &self.constness,
1444 &self.movability,
1445 &self.asyncness,
1446 &self.capture,
1447 &self.or1_token,
1448 &self.inputs,
1449 &self.or2_token,
1450 &self.output,
1451 &self.body,
1452 )
1453 .locate_as_group(locator, file_path, code, offset)
1454 }
1455}
1456
1457impl Locate for syn::ExprConst {
1458 fn find_loc(
1459 &self,
1460 locator: &mut LocatorGuard,
1461 file_path: &'static str,
1462 code: &str,
1463 offset: usize,
1464 ) -> Location {
1465 (&self.attrs, &self.const_token, &self.block)
1466 .locate_as_group(locator, file_path, code, offset)
1467 }
1468}
1469
1470impl Locate for syn::ExprContinue {
1471 fn find_loc(
1472 &self,
1473 locator: &mut LocatorGuard,
1474 file_path: &'static str,
1475 code: &str,
1476 offset: usize,
1477 ) -> Location {
1478 (&self.attrs, &self.continue_token, &self.label)
1479 .locate_as_group(locator, file_path, code, offset)
1480 }
1481}
1482
1483impl Locate for syn::ExprField {
1484 fn find_loc(
1485 &self,
1486 locator: &mut LocatorGuard,
1487 file_path: &'static str,
1488 code: &str,
1489 offset: usize,
1490 ) -> Location {
1491 (&self.attrs, &self.base, &self.dot_token, &self.member)
1492 .locate_as_group(locator, file_path, code, offset)
1493 }
1494}
1495
1496impl Locate for syn::ExprForLoop {
1497 fn find_loc(
1498 &self,
1499 locator: &mut LocatorGuard,
1500 file_path: &'static str,
1501 code: &str,
1502 offset: usize,
1503 ) -> Location {
1504 (
1505 &self.attrs,
1506 &self.label,
1507 &self.for_token,
1508 &self.pat,
1509 &self.in_token,
1510 &self.expr,
1511 &self.body,
1512 )
1513 .locate_as_group(locator, file_path, code, offset)
1514 }
1515}
1516
1517impl Locate for syn::ExprGroup {
1518 fn find_loc(
1519 &self,
1520 locator: &mut LocatorGuard,
1521 file_path: &'static str,
1522 code: &str,
1523 offset: usize,
1524 ) -> Location {
1525 (&self.attrs, &self.group_token, &self.expr)
1526 .locate_as_group(locator, file_path, code, offset)
1527 }
1528}
1529
1530impl Locate for syn::ExprIf {
1531 fn find_loc(
1532 &self,
1533 locator: &mut LocatorGuard,
1534 file_path: &'static str,
1535 code: &str,
1536 offset: usize,
1537 ) -> Location {
1538 if let Some((else_token, else_branch)) = &self.else_branch {
1539 (
1540 &self.attrs,
1541 &self.if_token,
1542 &self.cond,
1543 &self.then_branch,
1544 else_token,
1545 else_branch,
1546 )
1547 .locate_as_group(locator, file_path, code, offset)
1548 } else {
1549 (&self.attrs, &self.if_token, &self.cond, &self.then_branch)
1550 .locate_as_group(locator, file_path, code, offset)
1551 }
1552 }
1553}
1554
1555impl Locate for syn::ExprIndex {
1556 fn find_loc(
1557 &self,
1558 locator: &mut LocatorGuard,
1559 file_path: &'static str,
1560 code: &str,
1561 offset: usize,
1562 ) -> Location {
1563 Surround {
1564 front: (&self.attrs, &self.expr),
1565 surround: &self.bracket_token,
1566 inner: &self.index,
1567 back: (),
1568 }
1569 .locate(locator, file_path, code, offset)
1570 }
1571}
1572
1573impl Locate for syn::ExprInfer {
1574 fn find_loc(
1575 &self,
1576 locator: &mut LocatorGuard,
1577 file_path: &'static str,
1578 code: &str,
1579 offset: usize,
1580 ) -> Location {
1581 (&self.attrs, &self.underscore_token).locate_as_group(locator, file_path, code, offset)
1582 }
1583}
1584
1585impl Locate for syn::ExprLet {
1586 fn find_loc(
1587 &self,
1588 locator: &mut LocatorGuard,
1589 file_path: &'static str,
1590 code: &str,
1591 offset: usize,
1592 ) -> Location {
1593 (
1594 &self.attrs,
1595 &self.let_token,
1596 &self.pat,
1597 &self.eq_token,
1598 &self.expr,
1599 )
1600 .locate_as_group(locator, file_path, code, offset)
1601 }
1602}
1603
1604impl Locate for syn::ExprLit {
1605 fn find_loc(
1606 &self,
1607 locator: &mut LocatorGuard,
1608 file_path: &'static str,
1609 code: &str,
1610 offset: usize,
1611 ) -> Location {
1612 (&self.attrs, &self.lit).locate_as_group(locator, file_path, code, offset)
1613 }
1614}
1615
1616impl Locate for syn::ExprLoop {
1617 fn find_loc(
1618 &self,
1619 locator: &mut LocatorGuard,
1620 file_path: &'static str,
1621 code: &str,
1622 offset: usize,
1623 ) -> Location {
1624 (&self.attrs, &self.label, &self.loop_token, &self.body)
1625 .locate_as_group(locator, file_path, code, offset)
1626 }
1627}
1628
1629impl Locate for syn::ExprMacro {
1630 fn find_loc(
1631 &self,
1632 locator: &mut LocatorGuard,
1633 file_path: &'static str,
1634 code: &str,
1635 offset: usize,
1636 ) -> Location {
1637 (&self.attrs, &self.mac).locate_as_group(locator, file_path, code, offset)
1638 }
1639}
1640
1641impl Locate for syn::ExprMatch {
1642 fn find_loc(
1643 &self,
1644 locator: &mut LocatorGuard,
1645 file_path: &'static str,
1646 code: &str,
1647 offset: usize,
1648 ) -> Location {
1649 Surround {
1650 front: (&self.attrs, &self.match_token, &self.expr),
1651 surround: &self.brace_token,
1652 inner: &self.arms,
1653 back: (),
1654 }
1655 .locate(locator, file_path, code, offset)
1656 }
1657}
1658
1659impl Locate for syn::ExprMethodCall {
1660 fn find_loc(
1661 &self,
1662 locator: &mut LocatorGuard,
1663 file_path: &'static str,
1664 code: &str,
1665 offset: usize,
1666 ) -> Location {
1667 Surround {
1668 front: (
1669 &self.attrs,
1670 &self.receiver,
1671 &self.dot_token,
1672 &self.method,
1673 &self.turbofish,
1674 ),
1675 surround: &self.paren_token,
1676 inner: &self.args,
1677 back: (),
1678 }
1679 .locate(locator, file_path, code, offset)
1680 }
1681}
1682
1683impl Locate for syn::ExprParen {
1684 fn find_loc(
1685 &self,
1686 locator: &mut LocatorGuard,
1687 file_path: &'static str,
1688 code: &str,
1689 offset: usize,
1690 ) -> Location {
1691 Surround {
1692 front: &self.attrs,
1693 surround: &self.paren_token,
1694 inner: &self.expr,
1695 back: (),
1696 }
1697 .locate(locator, file_path, code, offset)
1698 }
1699}
1700
1701impl Locate for syn::ExprPath {
1702 fn find_loc(
1703 &self,
1704 locator: &mut LocatorGuard,
1705 file_path: &'static str,
1706 code: &str,
1707 offset: usize,
1708 ) -> Location {
1709 if let Some(qself) = &self.qself {
1710 Qualified {
1711 front: &self.attrs,
1712 qself,
1713 path: &self.path,
1714 back: (),
1715 }
1716 .locate(locator, file_path, code, offset)
1717 } else {
1718 (&self.attrs, &self.path).locate_as_group(locator, file_path, code, offset)
1719 }
1720 }
1721}
1722
1723impl Locate for syn::ExprRange {
1724 fn find_loc(
1725 &self,
1726 locator: &mut LocatorGuard,
1727 file_path: &'static str,
1728 code: &str,
1729 offset: usize,
1730 ) -> Location {
1731 match (&self.start, &self.end) {
1732 (Some(start), Some(end)) => (&self.attrs, start, &self.limits, end)
1733 .locate_as_group(locator, file_path, code, offset),
1734 (Some(start), None) => {
1735 (&self.attrs, start, &self.limits).locate_as_group(locator, file_path, code, offset)
1736 }
1737 (None, Some(end)) => {
1738 (&self.attrs, &self.limits, end).locate_as_group(locator, file_path, code, offset)
1739 }
1740 (None, None) => {
1741 (&self.attrs, &self.limits).locate_as_group(locator, file_path, code, offset)
1742 }
1743 }
1744 }
1745}
1746
1747impl Locate for syn::ExprRawAddr {
1748 fn find_loc(
1749 &self,
1750 locator: &mut LocatorGuard,
1751 file_path: &'static str,
1752 code: &str,
1753 offset: usize,
1754 ) -> Location {
1755 (
1756 &self.attrs,
1757 &self.and_token,
1758 &self.raw,
1759 &self.mutability,
1760 &self.expr,
1761 )
1762 .locate_as_group(locator, file_path, code, offset)
1763 }
1764}
1765
1766impl Locate for syn::ExprReference {
1767 fn find_loc(
1768 &self,
1769 locator: &mut LocatorGuard,
1770 file_path: &'static str,
1771 code: &str,
1772 offset: usize,
1773 ) -> Location {
1774 (&self.attrs, &self.and_token, &self.mutability, &self.expr)
1775 .locate_as_group(locator, file_path, code, offset)
1776 }
1777}
1778
1779impl Locate for syn::ExprRepeat {
1780 fn find_loc(
1781 &self,
1782 locator: &mut LocatorGuard,
1783 file_path: &'static str,
1784 code: &str,
1785 offset: usize,
1786 ) -> Location {
1787 Surround {
1788 front: &self.attrs,
1789 surround: &self.bracket_token,
1790 inner: (&self.expr, &self.semi_token, &self.len),
1791 back: (),
1792 }
1793 .locate(locator, file_path, code, offset)
1794 }
1795}
1796
1797impl Locate for syn::ExprReturn {
1798 fn find_loc(
1799 &self,
1800 locator: &mut LocatorGuard,
1801 file_path: &'static str,
1802 code: &str,
1803 offset: usize,
1804 ) -> Location {
1805 (&self.attrs, &self.return_token, &self.expr)
1806 .locate_as_group(locator, file_path, code, offset)
1807 }
1808}
1809
1810impl Locate for syn::ExprStruct {
1811 fn find_loc(
1812 &self,
1813 locator: &mut LocatorGuard,
1814 file_path: &'static str,
1815 code: &str,
1816 offset: usize,
1817 ) -> Location {
1818 let front_loc = if let Some(qself) = &self.qself {
1819 Qualified {
1820 front: &self.attrs,
1821 qself,
1822 path: &self.path,
1823 back: (),
1824 }
1825 .locate(locator, file_path, code, offset)
1826 } else {
1827 (&self.attrs, &self.path).locate_as_group(locator, file_path, code, offset)
1828 };
1829
1830 let back_loc = Surround {
1831 front: (),
1832 surround: &self.brace_token,
1833 inner: (&self.fields, &self.dot2_token, &self.rest),
1834 back: (),
1835 }
1836 .locate(locator, file_path, code, front_loc.end);
1837
1838 Location {
1839 file_path,
1840 start: front_loc.start,
1841 end: back_loc.end,
1842 }
1843 }
1844}
1845
1846impl Locate for syn::ExprTry {
1847 fn find_loc(
1848 &self,
1849 locator: &mut LocatorGuard,
1850 file_path: &'static str,
1851 code: &str,
1852 offset: usize,
1853 ) -> Location {
1854 (&self.attrs, &self.expr, &self.question_token)
1855 .locate_as_group(locator, file_path, code, offset)
1856 }
1857}
1858
1859impl Locate for syn::ExprTryBlock {
1860 fn find_loc(
1861 &self,
1862 locator: &mut LocatorGuard,
1863 file_path: &'static str,
1864 code: &str,
1865 offset: usize,
1866 ) -> Location {
1867 (&self.attrs, &self.try_token, &self.block)
1868 .locate_as_group(locator, file_path, code, offset)
1869 }
1870}
1871
1872impl Locate for syn::ExprTuple {
1873 fn find_loc(
1874 &self,
1875 locator: &mut LocatorGuard,
1876 file_path: &'static str,
1877 code: &str,
1878 offset: usize,
1879 ) -> Location {
1880 Surround {
1881 front: &self.attrs,
1882 surround: &self.paren_token,
1883 inner: &self.elems,
1884 back: (),
1885 }
1886 .locate(locator, file_path, code, offset)
1887 }
1888}
1889
1890impl Locate for syn::ExprUnary {
1891 fn find_loc(
1892 &self,
1893 locator: &mut LocatorGuard,
1894 file_path: &'static str,
1895 code: &str,
1896 offset: usize,
1897 ) -> Location {
1898 (&self.attrs, &self.op, &self.expr).locate_as_group(locator, file_path, code, offset)
1899 }
1900}
1901
1902impl Locate for syn::ExprUnsafe {
1903 fn find_loc(
1904 &self,
1905 locator: &mut LocatorGuard,
1906 file_path: &'static str,
1907 code: &str,
1908 offset: usize,
1909 ) -> Location {
1910 (&self.attrs, &self.unsafe_token, &self.block)
1911 .locate_as_group(locator, file_path, code, offset)
1912 }
1913}
1914
1915impl Locate for syn::ExprWhile {
1916 fn find_loc(
1917 &self,
1918 locator: &mut LocatorGuard,
1919 file_path: &'static str,
1920 code: &str,
1921 offset: usize,
1922 ) -> Location {
1923 (
1924 &self.attrs,
1925 &self.label,
1926 &self.while_token,
1927 &self.cond,
1928 &self.body,
1929 )
1930 .locate_as_group(locator, file_path, code, offset)
1931 }
1932}
1933
1934impl Locate for syn::ExprYield {
1935 fn find_loc(
1936 &self,
1937 locator: &mut LocatorGuard,
1938 file_path: &'static str,
1939 code: &str,
1940 offset: usize,
1941 ) -> Location {
1942 (&self.attrs, &self.yield_token, &self.expr)
1943 .locate_as_group(locator, file_path, code, offset)
1944 }
1945}
1946
1947impl Locate for syn::Field {
1948 fn find_loc(
1949 &self,
1950 locator: &mut LocatorGuard,
1951 file_path: &'static str,
1952 code: &str,
1953 offset: usize,
1954 ) -> Location {
1955 (
1956 &self.attrs,
1957 &self.vis,
1958 &self.mutability,
1959 &self.ident,
1960 &self.colon_token,
1961 &self.ty,
1962 )
1963 .locate_as_group(locator, file_path, code, offset)
1964 }
1965}
1966
1967impl Locate for syn::FieldMutability {
1968 fn find_loc(
1969 &self,
1970 _: &mut LocatorGuard,
1971 file_path: &'static str,
1972 _code: &str,
1973 offset: usize,
1974 ) -> Location {
1975 Location {
1976 file_path,
1977 start: offset,
1978 end: offset,
1979 }
1980 }
1981}
1982
1983impl Locate for syn::FieldPat {
1988 fn find_loc(
1989 &self,
1990 locator: &mut LocatorGuard,
1991 file_path: &'static str,
1992 code: &str,
1993 offset: usize,
1994 ) -> Location {
1995 if self.colon_token.is_some() || !matches!(self.member, syn::Member::Named(_)) {
1996 (&self.attrs, &self.member, &self.colon_token, &self.pat)
1997 .locate_as_group(locator, file_path, code, offset)
1998 } else {
1999 let loc = (&self.attrs, &self.colon_token, &self.pat)
2000 .locate_as_group(locator, file_path, code, offset);
2001 self.member
2002 .locate(locator, file_path, code, self.attrs._location(locator).end);
2003 loc
2004 }
2005 }
2006}
2007
2008impl Locate for syn::Fields {
2009 fn find_loc(
2010 &self,
2011 locator: &mut LocatorGuard,
2012 file_path: &'static str,
2013 code: &str,
2014 offset: usize,
2015 ) -> Location {
2016 match self {
2017 Self::Named(v) => v.locate(locator, file_path, code, offset),
2018 Self::Unnamed(v) => v.locate(locator, file_path, code, offset),
2019 Self::Unit => Location {
2020 file_path,
2021 start: offset,
2022 end: offset,
2023 },
2024 }
2025 }
2026}
2027
2028impl Locate for syn::FieldsNamed {
2029 fn find_loc(
2030 &self,
2031 locator: &mut LocatorGuard,
2032 file_path: &'static str,
2033 code: &str,
2034 offset: usize,
2035 ) -> Location {
2036 Surround {
2037 front: (),
2038 surround: &self.brace_token,
2039 inner: &self.named,
2040 back: (),
2041 }
2042 .locate(locator, file_path, code, offset)
2043 }
2044}
2045
2046impl Locate for syn::FieldsUnnamed {
2047 fn find_loc(
2048 &self,
2049 locator: &mut LocatorGuard,
2050 file_path: &'static str,
2051 code: &str,
2052 offset: usize,
2053 ) -> Location {
2054 Surround {
2055 front: (),
2056 surround: &self.paren_token,
2057 inner: &self.unnamed,
2058 back: (),
2059 }
2060 .locate(locator, file_path, code, offset)
2061 }
2062}
2063
2064impl Locate for syn::FieldValue {
2069 fn find_loc(
2070 &self,
2071 locator: &mut LocatorGuard,
2072 file_path: &'static str,
2073 code: &str,
2074 offset: usize,
2075 ) -> Location {
2076 if self.colon_token.is_some() || !matches!(self.member, syn::Member::Named(_)) {
2077 (&self.attrs, &self.member, &self.colon_token, &self.expr)
2078 .locate_as_group(locator, file_path, code, offset)
2079 } else {
2080 let loc = (&self.attrs, &self.member, &self.colon_token)
2081 .locate_as_group(locator, file_path, code, offset);
2082 self.expr
2083 .locate(locator, file_path, code, self.attrs._location(locator).end);
2084 loc
2085 }
2086 }
2087}
2088
2089impl Locate for syn::File {
2090 fn find_loc(
2091 &self,
2092 locator: &mut LocatorGuard,
2093 file_path: &'static str,
2094 code: &str,
2095 offset: usize,
2096 ) -> Location {
2097 (&self.attrs, &self.items).locate_as_group(locator, file_path, code, offset)
2098 }
2099}
2100
2101impl Locate for syn::FnArg {
2102 fn find_loc(
2103 &self,
2104 locator: &mut LocatorGuard,
2105 file_path: &'static str,
2106 code: &str,
2107 offset: usize,
2108 ) -> Location {
2109 match self {
2110 Self::Receiver(v) => v.locate(locator, file_path, code, offset),
2111 Self::Typed(v) => v.locate(locator, file_path, code, offset),
2112 }
2113 }
2114}
2115
2116impl Locate for syn::ForeignItem {
2117 fn find_loc(
2118 &self,
2119 locator: &mut LocatorGuard,
2120 file_path: &'static str,
2121 code: &str,
2122 offset: usize,
2123 ) -> Location {
2124 match self {
2125 Self::Fn(v) => v.locate(locator, file_path, code, offset),
2126 Self::Static(v) => v.locate(locator, file_path, code, offset),
2127 Self::Type(v) => v.locate(locator, file_path, code, offset),
2128 Self::Macro(v) => v.locate(locator, file_path, code, offset),
2129 Self::Verbatim(_) => Location {
2130 file_path,
2131 start: offset,
2132 end: offset,
2133 },
2134 _ => Location {
2135 file_path,
2136 start: offset,
2137 end: offset,
2138 },
2139 }
2140 }
2141}
2142
2143impl Locate for syn::ForeignItemFn {
2144 fn find_loc(
2145 &self,
2146 locator: &mut LocatorGuard,
2147 file_path: &'static str,
2148 code: &str,
2149 offset: usize,
2150 ) -> Location {
2151 (&self.attrs, &self.vis, &self.sig, &self.semi_token)
2152 .locate_as_group(locator, file_path, code, offset)
2153 }
2154}
2155
2156impl Locate for syn::ForeignItemStatic {
2157 fn find_loc(
2158 &self,
2159 locator: &mut LocatorGuard,
2160 file_path: &'static str,
2161 code: &str,
2162 offset: usize,
2163 ) -> Location {
2164 (
2165 &self.attrs,
2166 &self.vis,
2167 &self.static_token,
2168 &self.mutability,
2169 &self.ident,
2170 &self.colon_token,
2171 &self.ty,
2172 &self.semi_token,
2173 )
2174 .locate_as_group(locator, file_path, code, offset)
2175 }
2176}
2177
2178impl Locate for syn::ForeignItemType {
2179 fn find_loc(
2180 &self,
2181 locator: &mut LocatorGuard,
2182 file_path: &'static str,
2183 code: &str,
2184 offset: usize,
2185 ) -> Location {
2186 (
2187 &self.attrs,
2188 &self.vis,
2189 &self.type_token,
2190 &self.ident,
2191 &self.generics,
2192 &self.semi_token,
2193 )
2194 .locate_as_group(locator, file_path, code, offset)
2195 }
2196}
2197
2198impl Locate for syn::ForeignItemMacro {
2199 fn find_loc(
2200 &self,
2201 locator: &mut LocatorGuard,
2202 file_path: &'static str,
2203 code: &str,
2204 offset: usize,
2205 ) -> Location {
2206 (&self.attrs, &self.mac, &self.semi_token).locate_as_group(locator, file_path, code, offset)
2207 }
2208}
2209
2210impl Locate for syn::GenericArgument {
2211 fn find_loc(
2212 &self,
2213 locator: &mut LocatorGuard,
2214 file_path: &'static str,
2215 code: &str,
2216 offset: usize,
2217 ) -> Location {
2218 match self {
2219 Self::Lifetime(v) => v.locate(locator, file_path, code, offset),
2220 Self::Type(v) => v.locate(locator, file_path, code, offset),
2221 Self::Const(v) => v.locate(locator, file_path, code, offset),
2222 Self::AssocType(v) => v.locate(locator, file_path, code, offset),
2223 Self::AssocConst(v) => v.locate(locator, file_path, code, offset),
2224 Self::Constraint(v) => v.locate(locator, file_path, code, offset),
2225 _ => Location {
2226 file_path,
2227 start: offset,
2228 end: offset,
2229 },
2230 }
2231 }
2232}
2233
2234impl Locate for syn::GenericParam {
2235 fn find_loc(
2236 &self,
2237 locator: &mut LocatorGuard,
2238 file_path: &'static str,
2239 code: &str,
2240 offset: usize,
2241 ) -> Location {
2242 match self {
2243 Self::Lifetime(v) => v.locate(locator, file_path, code, offset),
2244 Self::Type(v) => v.locate(locator, file_path, code, offset),
2245 Self::Const(v) => v.locate(locator, file_path, code, offset),
2246 }
2247 }
2248}
2249
2250impl Locate for syn::Generics {
2251 fn find_loc(
2252 &self,
2253 locator: &mut LocatorGuard,
2254 file_path: &'static str,
2255 code: &str,
2256 offset: usize,
2257 ) -> Location {
2258 (
2259 &self.lt_token,
2260 &self.params,
2261 &self.gt_token,
2262 &self.where_clause,
2263 )
2264 .locate_as_group(locator, file_path, code, offset)
2265 }
2266}
2267
2268impl Locate for syn::Ident {
2269 fn find_loc(
2270 &self,
2271 _: &mut LocatorGuard,
2272 file_path: &'static str,
2273 code: &str,
2274 offset: usize,
2275 ) -> Location {
2276 let cur_code = &code[offset..];
2277
2278 let ident = self.to_string();
2279 let start = offset
2280 + cur_code
2281 .find(&ident)
2282 .unwrap_or_else(|| panic!("expected `{ident}` from `{cur_code}`"));
2283
2284 Location {
2285 file_path,
2286 start,
2287 end: start + ident.len(),
2288 }
2289 }
2290}
2291
2292impl Locate for syn::ImplItem {
2293 fn find_loc(
2294 &self,
2295 locator: &mut LocatorGuard,
2296 file_path: &'static str,
2297 code: &str,
2298 offset: usize,
2299 ) -> Location {
2300 match self {
2301 Self::Const(v) => v.locate(locator, file_path, code, offset),
2302 Self::Fn(v) => v.locate(locator, file_path, code, offset),
2303 Self::Type(v) => v.locate(locator, file_path, code, offset),
2304 Self::Macro(v) => v.locate(locator, file_path, code, offset),
2305 Self::Verbatim(_) => Location {
2306 file_path,
2307 start: offset,
2308 end: offset,
2309 },
2310 _ => Location {
2311 file_path,
2312 start: offset,
2313 end: offset,
2314 },
2315 }
2316 }
2317}
2318
2319impl Locate for syn::ImplItemConst {
2320 fn find_loc(
2321 &self,
2322 locator: &mut LocatorGuard,
2323 file_path: &'static str,
2324 code: &str,
2325 offset: usize,
2326 ) -> Location {
2327 (
2328 &self.attrs,
2329 &self.vis,
2330 &self.defaultness,
2331 &self.const_token,
2332 &self.ident,
2333 &self.generics,
2334 &self.colon_token,
2335 &self.ty,
2336 &self.eq_token,
2337 &self.expr,
2338 &self.semi_token,
2339 )
2340 .locate_as_group(locator, file_path, code, offset)
2341 }
2342}
2343
2344impl Locate for syn::ImplItemFn {
2345 fn find_loc(
2346 &self,
2347 locator: &mut LocatorGuard,
2348 file_path: &'static str,
2349 code: &str,
2350 offset: usize,
2351 ) -> Location {
2352 (
2353 &self.attrs,
2354 &self.vis,
2355 &self.defaultness,
2356 &self.sig,
2357 &self.block,
2358 )
2359 .locate_as_group(locator, file_path, code, offset)
2360 }
2361}
2362
2363impl Locate for syn::ImplItemType {
2364 fn find_loc(
2365 &self,
2366 locator: &mut LocatorGuard,
2367 file_path: &'static str,
2368 code: &str,
2369 offset: usize,
2370 ) -> Location {
2371 (
2372 &self.attrs,
2373 &self.vis,
2374 &self.defaultness,
2375 &self.type_token,
2376 &self.ident,
2377 &self.generics,
2378 &self.eq_token,
2379 &self.ty,
2380 &self.semi_token,
2381 )
2382 .locate_as_group(locator, file_path, code, offset)
2383 }
2384}
2385
2386impl Locate for syn::ImplItemMacro {
2387 fn find_loc(
2388 &self,
2389 locator: &mut LocatorGuard,
2390 file_path: &'static str,
2391 code: &str,
2392 offset: usize,
2393 ) -> Location {
2394 (&self.attrs, &self.mac, &self.semi_token).locate_as_group(locator, file_path, code, offset)
2395 }
2396}
2397
2398impl Locate for syn::ImplRestriction {
2399 fn find_loc(
2400 &self,
2401 _: &mut LocatorGuard,
2402 file_path: &'static str,
2403 _code: &str,
2404 offset: usize,
2405 ) -> Location {
2406 Location {
2407 file_path,
2408 start: offset,
2409 end: offset,
2410 }
2411 }
2412}
2413
2414impl Locate for syn::Index {
2415 fn find_loc(
2416 &self,
2417 _: &mut LocatorGuard,
2418 file_path: &'static str,
2419 code: &str,
2420 offset: usize,
2421 ) -> Location {
2422 let value = self.index.to_string();
2423 helper::str_location(file_path, code, offset, &value)
2424 }
2425}
2426
2427impl Locate for syn::Item {
2428 fn find_loc(
2429 &self,
2430 locator: &mut LocatorGuard,
2431 file_path: &'static str,
2432 code: &str,
2433 offset: usize,
2434 ) -> Location {
2435 match self {
2436 Self::Const(v) => v.locate(locator, file_path, code, offset),
2437 Self::Enum(v) => v.locate(locator, file_path, code, offset),
2438 Self::ExternCrate(v) => v.locate(locator, file_path, code, offset),
2439 Self::Fn(v) => v.locate(locator, file_path, code, offset),
2440 Self::ForeignMod(v) => v.locate(locator, file_path, code, offset),
2441 Self::Impl(v) => v.locate(locator, file_path, code, offset),
2442 Self::Macro(v) => v.locate(locator, file_path, code, offset),
2443 Self::Mod(v) => v.locate(locator, file_path, code, offset),
2444 Self::Static(v) => v.locate(locator, file_path, code, offset),
2445 Self::Struct(v) => v.locate(locator, file_path, code, offset),
2446 Self::Trait(v) => v.locate(locator, file_path, code, offset),
2447 Self::TraitAlias(v) => v.locate(locator, file_path, code, offset),
2448 Self::Type(v) => v.locate(locator, file_path, code, offset),
2449 Self::Union(v) => v.locate(locator, file_path, code, offset),
2450 Self::Use(v) => v.locate(locator, file_path, code, offset),
2451 Self::Verbatim(_) => Location {
2452 file_path,
2453 start: offset,
2454 end: offset,
2455 },
2456 _ => Location {
2457 file_path,
2458 start: offset,
2459 end: offset,
2460 },
2461 }
2462 }
2463}
2464
2465impl Locate for syn::ItemConst {
2466 fn find_loc(
2467 &self,
2468 locator: &mut LocatorGuard,
2469 file_path: &'static str,
2470 code: &str,
2471 offset: usize,
2472 ) -> Location {
2473 (
2474 &self.attrs,
2475 &self.vis,
2476 &self.const_token,
2477 &self.ident,
2478 &self.generics,
2479 &self.colon_token,
2480 &self.ty,
2481 &self.eq_token,
2482 &self.expr,
2483 &self.semi_token,
2484 )
2485 .locate_as_group(locator, file_path, code, offset)
2486 }
2487}
2488
2489impl Locate for syn::ItemEnum {
2490 fn find_loc(
2491 &self,
2492 locator: &mut LocatorGuard,
2493 file_path: &'static str,
2494 code: &str,
2495 offset: usize,
2496 ) -> Location {
2497 Surround {
2498 front: (
2499 &self.attrs,
2500 &self.vis,
2501 &self.enum_token,
2502 &self.ident,
2503 &self.generics,
2504 ),
2505 surround: &self.brace_token,
2506 inner: &self.variants,
2507 back: (),
2508 }
2509 .locate(locator, file_path, code, offset)
2510 }
2511}
2512
2513impl Locate for syn::ItemExternCrate {
2514 fn find_loc(
2515 &self,
2516 locator: &mut LocatorGuard,
2517 file_path: &'static str,
2518 code: &str,
2519 offset: usize,
2520 ) -> Location {
2521 if let Some((as_token, rename)) = &self.rename {
2522 (
2523 &self.attrs,
2524 &self.vis,
2525 &self.extern_token,
2526 &self.crate_token,
2527 &self.ident,
2528 as_token,
2529 rename,
2530 &self.semi_token,
2531 )
2532 .locate_as_group(locator, file_path, code, offset)
2533 } else {
2534 (
2535 &self.attrs,
2536 &self.vis,
2537 &self.extern_token,
2538 &self.crate_token,
2539 &self.ident,
2540 &self.semi_token,
2541 )
2542 .locate_as_group(locator, file_path, code, offset)
2543 }
2544 }
2545}
2546
2547impl Locate for syn::ItemFn {
2548 fn find_loc(
2549 &self,
2550 locator: &mut LocatorGuard,
2551 file_path: &'static str,
2552 code: &str,
2553 offset: usize,
2554 ) -> Location {
2555 (&self.attrs, &self.vis, &self.sig, &self.block)
2556 .locate_as_group(locator, file_path, code, offset)
2557 }
2558}
2559
2560impl Locate for syn::ItemForeignMod {
2561 fn find_loc(
2562 &self,
2563 locator: &mut LocatorGuard,
2564 file_path: &'static str,
2565 code: &str,
2566 offset: usize,
2567 ) -> Location {
2568 Surround {
2569 front: (&self.attrs, &self.unsafety, &self.abi),
2570 surround: &self.brace_token,
2571 inner: &self.items,
2572 back: (),
2573 }
2574 .locate(locator, file_path, code, offset)
2575 }
2576}
2577
2578impl Locate for syn::ItemImpl {
2579 fn find_loc(
2580 &self,
2581 locator: &mut LocatorGuard,
2582 file_path: &'static str,
2583 code: &str,
2584 offset: usize,
2585 ) -> Location {
2586 if let Some((exc_token, path, for_token)) = &self.trait_ {
2587 Surround {
2588 front: (
2589 &self.attrs,
2590 &self.defaultness,
2591 &self.unsafety,
2592 &self.impl_token,
2593 &self.generics.lt_token,
2595 &self.generics.params,
2596 &self.generics.gt_token,
2597 exc_token,
2598 path,
2599 for_token,
2600 &self.self_ty,
2601 &self.generics.where_clause,
2602 ),
2603 surround: &self.brace_token,
2604 inner: &self.items,
2605 back: (),
2606 }
2607 .locate(locator, file_path, code, offset)
2608 } else {
2609 Surround {
2610 front: (
2611 &self.attrs,
2612 &self.defaultness,
2613 &self.unsafety,
2614 &self.impl_token,
2615 &self.generics.lt_token,
2617 &self.generics.params,
2618 &self.generics.gt_token,
2619 &self.self_ty,
2620 &self.generics.where_clause,
2621 ),
2622 surround: &self.brace_token,
2623 inner: &self.items,
2624 back: (),
2625 }
2626 .locate(locator, file_path, code, offset)
2627 }
2628 }
2629}
2630
2631impl Locate for syn::ItemMacro {
2634 fn find_loc(
2635 &self,
2636 locator: &mut LocatorGuard,
2637 file_path: &'static str,
2638 code: &str,
2639 offset: usize,
2640 ) -> Location {
2641 Surround {
2642 front: (
2643 &self.attrs,
2644 &self.mac.path,
2645 &self.mac.bang_token,
2646 &self.ident,
2647 ),
2648 surround: &self.mac.delimiter,
2649 inner: (), back: &self.semi_token,
2651 }
2652 .locate(locator, file_path, code, offset)
2653 }
2654}
2655
2656impl Locate for syn::ItemMod {
2657 fn find_loc(
2658 &self,
2659 locator: &mut LocatorGuard,
2660 file_path: &'static str,
2661 code: &str,
2662 offset: usize,
2663 ) -> Location {
2664 match (&self.content, &self.semi) {
2665 (Some((brace, items)), Some(semi_token)) => Surround {
2666 front: (&self.attrs, &self.vis, &self.mod_token, &self.ident),
2667 surround: brace,
2668 inner: items,
2669 back: semi_token,
2670 }
2671 .locate(locator, file_path, code, offset),
2672 (Some((brace, items)), None) => Surround {
2673 front: (&self.attrs, &self.vis, &self.mod_token, &self.ident),
2674 surround: brace,
2675 inner: items,
2676 back: (),
2677 }
2678 .locate(locator, file_path, code, offset),
2679 (None, Some(semi_token)) => (
2680 &self.attrs,
2681 &self.vis,
2682 &self.mod_token,
2683 &self.ident,
2684 semi_token,
2685 )
2686 .locate_as_group(locator, file_path, code, offset),
2687 (None, None) => (&self.attrs, &self.vis, &self.mod_token, &self.ident)
2688 .locate_as_group(locator, file_path, code, offset),
2689 }
2690 }
2691}
2692
2693impl Locate for syn::ItemStatic {
2694 fn find_loc(
2695 &self,
2696 locator: &mut LocatorGuard,
2697 file_path: &'static str,
2698 code: &str,
2699 offset: usize,
2700 ) -> Location {
2701 (
2702 &self.attrs,
2703 &self.vis,
2704 &self.static_token,
2705 &self.mutability,
2706 &self.ident,
2707 &self.colon_token,
2708 &self.ty,
2709 &self.eq_token,
2710 &self.expr,
2711 &self.semi_token,
2712 )
2713 .locate_as_group(locator, file_path, code, offset)
2714 }
2715}
2716
2717impl Locate for syn::ItemStruct {
2718 fn find_loc(
2719 &self,
2720 locator: &mut LocatorGuard,
2721 file_path: &'static str,
2722 code: &str,
2723 offset: usize,
2724 ) -> Location {
2725 (
2726 &self.attrs,
2727 &self.vis,
2728 &self.struct_token,
2729 &self.ident,
2730 &self.generics,
2731 &self.fields,
2732 &self.semi_token,
2733 )
2734 .locate_as_group(locator, file_path, code, offset)
2735 }
2736}
2737
2738impl Locate for syn::ItemTrait {
2739 fn find_loc(
2740 &self,
2741 locator: &mut LocatorGuard,
2742 file_path: &'static str,
2743 code: &str,
2744 offset: usize,
2745 ) -> Location {
2746 Surround {
2747 front: (
2748 &self.attrs,
2749 &self.vis,
2750 &self.unsafety,
2751 &self.auto_token,
2752 &self.restriction,
2753 &self.trait_token,
2754 &self.ident,
2755 &self.generics,
2756 &self.colon_token,
2757 &self.supertraits,
2758 ),
2759 surround: &self.brace_token,
2760 inner: &self.items,
2761 back: (),
2762 }
2763 .locate(locator, file_path, code, offset)
2764 }
2765}
2766
2767impl Locate for syn::ItemTraitAlias {
2768 fn find_loc(
2769 &self,
2770 locator: &mut LocatorGuard,
2771 file_path: &'static str,
2772 code: &str,
2773 offset: usize,
2774 ) -> Location {
2775 (
2776 &self.attrs,
2777 &self.vis,
2778 &self.trait_token,
2779 &self.ident,
2780 &self.generics,
2781 &self.eq_token,
2782 &self.bounds,
2783 &self.semi_token,
2784 )
2785 .locate_as_group(locator, file_path, code, offset)
2786 }
2787}
2788
2789impl Locate for syn::ItemType {
2790 fn find_loc(
2791 &self,
2792 locator: &mut LocatorGuard,
2793 file_path: &'static str,
2794 code: &str,
2795 offset: usize,
2796 ) -> Location {
2797 (
2798 &self.attrs,
2799 &self.vis,
2800 &self.type_token,
2801 &self.ident,
2802 &self.generics,
2803 &self.eq_token,
2804 &self.ty,
2805 &self.semi_token,
2806 )
2807 .locate_as_group(locator, file_path, code, offset)
2808 }
2809}
2810
2811impl Locate for syn::ItemUnion {
2812 fn find_loc(
2813 &self,
2814 locator: &mut LocatorGuard,
2815 file_path: &'static str,
2816 code: &str,
2817 offset: usize,
2818 ) -> Location {
2819 (
2820 &self.attrs,
2821 &self.vis,
2822 &self.union_token,
2823 &self.ident,
2824 &self.generics,
2825 &self.fields,
2826 )
2827 .locate_as_group(locator, file_path, code, offset)
2828 }
2829}
2830
2831impl Locate for syn::ItemUse {
2832 fn find_loc(
2833 &self,
2834 locator: &mut LocatorGuard,
2835 file_path: &'static str,
2836 code: &str,
2837 offset: usize,
2838 ) -> Location {
2839 (
2840 &self.attrs,
2841 &self.vis,
2842 &self.use_token,
2843 &self.leading_colon,
2844 &self.tree,
2845 &self.semi_token,
2846 )
2847 .locate_as_group(locator, file_path, code, offset)
2848 }
2849}
2850
2851impl Locate for syn::Label {
2852 fn find_loc(
2853 &self,
2854 locator: &mut LocatorGuard,
2855 file_path: &'static str,
2856 code: &str,
2857 offset: usize,
2858 ) -> Location {
2859 (&self.name, &self.colon_token).locate_as_group(locator, file_path, code, offset)
2860 }
2861}
2862
2863impl Locate for syn::Lifetime {
2864 fn find_loc(
2865 &self,
2866 locator: &mut LocatorGuard,
2867 file_path: &'static str,
2868 code: &str,
2869 offset: usize,
2870 ) -> Location {
2871 let cur_code = &code[offset..];
2872
2873 let start = offset
2874 + cur_code
2875 .find('\'')
2876 .unwrap_or_else(|| panic!("expected ' from {cur_code}"));
2877 let end = self.ident.locate(locator, file_path, code, start + 1).end;
2878
2879 Location {
2880 file_path,
2881 start,
2882 end,
2883 }
2884 }
2885}
2886
2887impl Locate for syn::LifetimeParam {
2888 fn find_loc(
2889 &self,
2890 locator: &mut LocatorGuard,
2891 file_path: &'static str,
2892 code: &str,
2893 offset: usize,
2894 ) -> Location {
2895 (&self.attrs, &self.lifetime, &self.colon_token, &self.bounds)
2896 .locate_as_group(locator, file_path, code, offset)
2897 }
2898}
2899
2900impl Locate for syn::Lit {
2901 fn find_loc(
2902 &self,
2903 locator: &mut LocatorGuard,
2904 file_path: &'static str,
2905 code: &str,
2906 offset: usize,
2907 ) -> Location {
2908 match self {
2909 Self::Str(v) => v.locate(locator, file_path, code, offset),
2910 Self::ByteStr(v) => v.locate(locator, file_path, code, offset),
2911 Self::CStr(v) => v.locate(locator, file_path, code, offset),
2912 Self::Byte(v) => v.locate(locator, file_path, code, offset),
2913 Self::Char(v) => v.locate(locator, file_path, code, offset),
2914 Self::Int(v) => v.locate(locator, file_path, code, offset),
2915 Self::Float(v) => v.locate(locator, file_path, code, offset),
2916 Self::Bool(v) => v.locate(locator, file_path, code, offset),
2917 Self::Verbatim(_) => Location {
2918 file_path,
2919 start: offset,
2920 end: offset,
2921 },
2922 _ => Location {
2923 file_path,
2924 start: offset,
2925 end: offset,
2926 },
2927 }
2928 }
2929}
2930
2931impl Locate for syn::LitStr {
2932 fn find_loc(
2933 &self,
2934 _: &mut LocatorGuard,
2935 file_path: &'static str,
2936 code: &str,
2937 offset: usize,
2938 ) -> Location {
2939 let lit = self.token().to_string();
2940 helper::str_location(file_path, code, offset, &lit)
2941 }
2942}
2943
2944impl Locate for syn::LitByteStr {
2945 fn find_loc(
2946 &self,
2947 _: &mut LocatorGuard,
2948 file_path: &'static str,
2949 code: &str,
2950 offset: usize,
2951 ) -> Location {
2952 let lit = self.token().to_string();
2953 helper::str_location(file_path, code, offset, &lit)
2954 }
2955}
2956
2957impl Locate for syn::LitCStr {
2958 fn find_loc(
2959 &self,
2960 _: &mut LocatorGuard,
2961 file_path: &'static str,
2962 code: &str,
2963 offset: usize,
2964 ) -> Location {
2965 let lit = self.token().to_string();
2966 helper::str_location(file_path, code, offset, &lit)
2967 }
2968}
2969
2970impl Locate for syn::LitByte {
2971 fn find_loc(
2972 &self,
2973 _: &mut LocatorGuard,
2974 file_path: &'static str,
2975 code: &str,
2976 offset: usize,
2977 ) -> Location {
2978 let lit = self.token().to_string();
2979 helper::str_location(file_path, code, offset, &lit)
2980 }
2981}
2982
2983impl Locate for syn::LitChar {
2984 fn find_loc(
2985 &self,
2986 _: &mut LocatorGuard,
2987 file_path: &'static str,
2988 code: &str,
2989 offset: usize,
2990 ) -> Location {
2991 let lit = self.token().to_string();
2992 helper::str_location(file_path, code, offset, &lit)
2993 }
2994}
2995
2996impl Locate for syn::LitInt {
2997 fn find_loc(
2998 &self,
2999 _: &mut LocatorGuard,
3000 file_path: &'static str,
3001 code: &str,
3002 offset: usize,
3003 ) -> Location {
3004 let lit = self.token().to_string();
3005 helper::str_location(file_path, code, offset, &lit)
3006 }
3007}
3008
3009impl Locate for syn::LitFloat {
3010 fn find_loc(
3011 &self,
3012 _: &mut LocatorGuard,
3013 file_path: &'static str,
3014 code: &str,
3015 offset: usize,
3016 ) -> Location {
3017 let lit = self.token().to_string();
3018 helper::str_location(file_path, code, offset, &lit)
3019 }
3020}
3021
3022impl Locate for syn::LitBool {
3023 fn find_loc(
3024 &self,
3025 _: &mut LocatorGuard,
3026 file_path: &'static str,
3027 code: &str,
3028 offset: usize,
3029 ) -> Location {
3030 let lit = self.token().to_string();
3031 helper::str_location(file_path, code, offset, &lit)
3032 }
3033}
3034
3035impl Locate for syn::Local {
3036 fn find_loc(
3037 &self,
3038 locator: &mut LocatorGuard,
3039 file_path: &'static str,
3040 code: &str,
3041 offset: usize,
3042 ) -> Location {
3043 (
3044 &self.attrs,
3045 &self.let_token,
3046 &self.pat,
3047 &self.init,
3048 &self.semi_token,
3049 )
3050 .locate_as_group(locator, file_path, code, offset)
3051 }
3052}
3053
3054impl Locate for syn::LocalInit {
3055 fn find_loc(
3056 &self,
3057 locator: &mut LocatorGuard,
3058 file_path: &'static str,
3059 code: &str,
3060 offset: usize,
3061 ) -> Location {
3062 if let Some((else_token, diverge)) = &self.diverge {
3063 (&self.eq_token, &self.expr, else_token, diverge)
3064 .locate_as_group(locator, file_path, code, offset)
3065 } else {
3066 (&self.eq_token, &self.expr).locate_as_group(locator, file_path, code, offset)
3067 }
3068 }
3069}
3070
3071impl Locate for syn::Macro {
3072 fn find_loc(
3073 &self,
3074 locator: &mut LocatorGuard,
3075 file_path: &'static str,
3076 code: &str,
3077 offset: usize,
3078 ) -> Location {
3079 match &self.delimiter {
3080 syn::MacroDelimiter::Paren(paren) => Surround {
3081 front: (&self.path, &self.bang_token),
3082 surround: paren,
3083 inner: (),
3084 back: (),
3085 }
3086 .locate(locator, file_path, code, offset),
3087 syn::MacroDelimiter::Brace(brace) => Surround {
3088 front: (&self.path, &self.bang_token),
3089 surround: brace,
3090 inner: (),
3091 back: (),
3092 }
3093 .locate(locator, file_path, code, offset),
3094 syn::MacroDelimiter::Bracket(bracket) => Surround {
3095 front: (&self.path, &self.bang_token),
3096 surround: bracket,
3097 inner: (),
3098 back: (),
3099 }
3100 .locate(locator, file_path, code, offset),
3101 }
3102 }
3103}
3104
3105impl Locate for syn::MacroDelimiter {
3106 fn find_loc(
3107 &self,
3108 locator: &mut LocatorGuard,
3109 file_path: &'static str,
3110 code: &str,
3111 offset: usize,
3112 ) -> Location {
3113 match self {
3114 Self::Paren(v) => v.locate(locator, file_path, code, offset),
3115 Self::Brace(v) => v.locate(locator, file_path, code, offset),
3116 Self::Bracket(v) => v.locate(locator, file_path, code, offset),
3117 }
3118 }
3119}
3120
3121impl Locate for syn::Member {
3122 fn find_loc(
3123 &self,
3124 locator: &mut LocatorGuard,
3125 file_path: &'static str,
3126 code: &str,
3127 offset: usize,
3128 ) -> Location {
3129 match self {
3130 Self::Named(v) => v.locate(locator, file_path, code, offset),
3131 Self::Unnamed(v) => v.locate(locator, file_path, code, offset),
3132 }
3133 }
3134}
3135
3136impl Locate for syn::Meta {
3137 fn find_loc(
3138 &self,
3139 locator: &mut LocatorGuard,
3140 file_path: &'static str,
3141 code: &str,
3142 offset: usize,
3143 ) -> Location {
3144 match self {
3145 Self::Path(v) => v.locate(locator, file_path, code, offset),
3146 Self::List(v) => v.locate(locator, file_path, code, offset),
3147 Self::NameValue(v) => v.locate(locator, file_path, code, offset),
3148 }
3149 }
3150}
3151
3152impl Locate for syn::MetaList {
3153 fn find_loc(
3154 &self,
3155 locator: &mut LocatorGuard,
3156 file_path: &'static str,
3157 code: &str,
3158 offset: usize,
3159 ) -> Location {
3160 match &self.delimiter {
3161 syn::MacroDelimiter::Paren(paren) => Surround {
3162 front: &self.path,
3163 surround: paren,
3164 inner: (),
3165 back: (),
3166 }
3167 .locate(locator, file_path, code, offset),
3168 syn::MacroDelimiter::Brace(brace) => Surround {
3169 front: &self.path,
3170 surround: brace,
3171 inner: (),
3172 back: (),
3173 }
3174 .locate(locator, file_path, code, offset),
3175 syn::MacroDelimiter::Bracket(bracket) => Surround {
3176 front: &self.path,
3177 surround: bracket,
3178 inner: (),
3179 back: (),
3180 }
3181 .locate(locator, file_path, code, offset),
3182 }
3183 }
3184}
3185
3186impl Locate for syn::MetaNameValue {
3187 fn find_loc(
3188 &self,
3189 locator: &mut LocatorGuard,
3190 file_path: &'static str,
3191 code: &str,
3192 offset: usize,
3193 ) -> Location {
3194 (&self.path, &self.eq_token, &self.value).locate_as_group(locator, file_path, code, offset)
3195 }
3196}
3197
3198impl Locate for syn::ParenthesizedGenericArguments {
3199 fn find_loc(
3200 &self,
3201 locator: &mut LocatorGuard,
3202 file_path: &'static str,
3203 code: &str,
3204 offset: usize,
3205 ) -> Location {
3206 Surround {
3207 front: (),
3208 surround: &self.paren_token,
3209 inner: &self.inputs,
3210 back: &self.output,
3211 }
3212 .locate(locator, file_path, code, offset)
3213 }
3214}
3215
3216impl Locate for syn::Pat {
3217 fn find_loc(
3218 &self,
3219 locator: &mut LocatorGuard,
3220 file_path: &'static str,
3221 code: &str,
3222 offset: usize,
3223 ) -> Location {
3224 match self {
3225 Self::Const(v) => v.locate(locator, file_path, code, offset),
3226 Self::Ident(v) => v.locate(locator, file_path, code, offset),
3227 Self::Lit(v) => v.locate(locator, file_path, code, offset),
3228 Self::Macro(v) => v.locate(locator, file_path, code, offset),
3229 Self::Or(v) => v.locate(locator, file_path, code, offset),
3230 Self::Paren(v) => v.locate(locator, file_path, code, offset),
3231 Self::Path(v) => v.locate(locator, file_path, code, offset),
3232 Self::Range(v) => v.locate(locator, file_path, code, offset),
3233 Self::Reference(v) => v.locate(locator, file_path, code, offset),
3234 Self::Rest(v) => v.locate(locator, file_path, code, offset),
3235 Self::Slice(v) => v.locate(locator, file_path, code, offset),
3236 Self::Struct(v) => v.locate(locator, file_path, code, offset),
3237 Self::Tuple(v) => v.locate(locator, file_path, code, offset),
3238 Self::TupleStruct(v) => v.locate(locator, file_path, code, offset),
3239 Self::Type(v) => v.locate(locator, file_path, code, offset),
3240 Self::Verbatim(_) => Location {
3241 file_path,
3242 start: offset,
3243 end: offset,
3244 },
3245 Self::Wild(v) => v.locate(locator, file_path, code, offset),
3246 _ => Location {
3247 file_path,
3248 start: offset,
3249 end: offset,
3250 },
3251 }
3252 }
3253}
3254
3255impl Locate for syn::PatIdent {
3256 fn find_loc(
3257 &self,
3258 locator: &mut LocatorGuard,
3259 file_path: &'static str,
3260 code: &str,
3261 offset: usize,
3262 ) -> Location {
3263 if let Some((at_token, subpat)) = &self.subpat {
3264 (
3265 &self.attrs,
3266 &self.by_ref,
3267 &self.mutability,
3268 &self.ident,
3269 at_token,
3270 subpat,
3271 )
3272 .locate_as_group(locator, file_path, code, offset)
3273 } else {
3274 (&self.attrs, &self.by_ref, &self.mutability, &self.ident)
3275 .locate_as_group(locator, file_path, code, offset)
3276 }
3277 }
3278}
3279
3280impl Locate for syn::PatOr {
3281 fn find_loc(
3282 &self,
3283 locator: &mut LocatorGuard,
3284 file_path: &'static str,
3285 code: &str,
3286 offset: usize,
3287 ) -> Location {
3288 (&self.attrs, &self.leading_vert, &self.cases)
3289 .locate_as_group(locator, file_path, code, offset)
3290 }
3291}
3292
3293impl Locate for syn::PatParen {
3294 fn find_loc(
3295 &self,
3296 locator: &mut LocatorGuard,
3297 file_path: &'static str,
3298 code: &str,
3299 offset: usize,
3300 ) -> Location {
3301 Surround {
3302 front: &self.attrs,
3303 surround: &self.paren_token,
3304 inner: &self.pat,
3305 back: (),
3306 }
3307 .locate(locator, file_path, code, offset)
3308 }
3309}
3310
3311impl Locate for syn::PatReference {
3312 fn find_loc(
3313 &self,
3314 locator: &mut LocatorGuard,
3315 file_path: &'static str,
3316 code: &str,
3317 offset: usize,
3318 ) -> Location {
3319 (&self.attrs, &self.and_token, &self.mutability, &self.pat)
3320 .locate_as_group(locator, file_path, code, offset)
3321 }
3322}
3323
3324impl Locate for syn::PatRest {
3325 fn find_loc(
3326 &self,
3327 locator: &mut LocatorGuard,
3328 file_path: &'static str,
3329 code: &str,
3330 offset: usize,
3331 ) -> Location {
3332 (&self.attrs, &self.dot2_token).locate_as_group(locator, file_path, code, offset)
3333 }
3334}
3335
3336impl Locate for syn::PatSlice {
3337 fn find_loc(
3338 &self,
3339 locator: &mut LocatorGuard,
3340 file_path: &'static str,
3341 code: &str,
3342 offset: usize,
3343 ) -> Location {
3344 Surround {
3345 front: &self.attrs,
3346 surround: &self.bracket_token,
3347 inner: &self.elems,
3348 back: (),
3349 }
3350 .locate(locator, file_path, code, offset)
3351 }
3352}
3353
3354impl Locate for syn::PatStruct {
3355 fn find_loc(
3356 &self,
3357 locator: &mut LocatorGuard,
3358 file_path: &'static str,
3359 code: &str,
3360 offset: usize,
3361 ) -> Location {
3362 let front_loc = if let Some(qself) = &self.qself {
3363 Qualified {
3364 front: &self.attrs,
3365 qself,
3366 path: &self.path,
3367 back: (),
3368 }
3369 .locate(locator, file_path, code, offset)
3370 } else {
3371 (&self.attrs, &self.path).locate_as_group(locator, file_path, code, offset)
3372 };
3373
3374 let back_loc = Surround {
3375 front: (),
3376 surround: &self.brace_token,
3377 inner: (&self.fields, &self.rest),
3378 back: (),
3379 }
3380 .locate(locator, file_path, code, front_loc.end);
3381
3382 Location {
3383 file_path,
3384 start: front_loc.start,
3385 end: back_loc.end,
3386 }
3387 }
3388}
3389
3390impl Locate for syn::PatTuple {
3391 fn find_loc(
3392 &self,
3393 locator: &mut LocatorGuard,
3394 file_path: &'static str,
3395 code: &str,
3396 offset: usize,
3397 ) -> Location {
3398 Surround {
3399 front: &self.attrs,
3400 surround: &self.paren_token,
3401 inner: &self.elems,
3402 back: (),
3403 }
3404 .locate(locator, file_path, code, offset)
3405 }
3406}
3407
3408impl Locate for syn::PatTupleStruct {
3409 fn find_loc(
3410 &self,
3411 locator: &mut LocatorGuard,
3412 file_path: &'static str,
3413 code: &str,
3414 offset: usize,
3415 ) -> Location {
3416 let front_loc = if let Some(qself) = &self.qself {
3417 Qualified {
3418 front: &self.attrs,
3419 qself,
3420 path: &self.path,
3421 back: (),
3422 }
3423 .locate(locator, file_path, code, offset)
3424 } else {
3425 (&self.attrs, &self.path).locate_as_group(locator, file_path, code, offset)
3426 };
3427
3428 let back_loc = Surround {
3429 front: (),
3430 surround: &self.paren_token,
3431 inner: &self.elems,
3432 back: (),
3433 }
3434 .locate(locator, file_path, code, front_loc.end);
3435
3436 Location {
3437 file_path,
3438 start: front_loc.start,
3439 end: back_loc.end,
3440 }
3441 }
3442}
3443
3444impl Locate for syn::PatType {
3445 fn find_loc(
3446 &self,
3447 locator: &mut LocatorGuard,
3448 file_path: &'static str,
3449 code: &str,
3450 offset: usize,
3451 ) -> Location {
3452 (&self.attrs, &self.pat, &self.colon_token, &self.ty)
3453 .locate_as_group(locator, file_path, code, offset)
3454 }
3455}
3456
3457impl Locate for syn::PatWild {
3458 fn find_loc(
3459 &self,
3460 locator: &mut LocatorGuard,
3461 file_path: &'static str,
3462 code: &str,
3463 offset: usize,
3464 ) -> Location {
3465 (&self.attrs, &self.underscore_token).locate_as_group(locator, file_path, code, offset)
3466 }
3467}
3468
3469impl Locate for syn::Path {
3470 fn find_loc(
3471 &self,
3472 locator: &mut LocatorGuard,
3473 file_path: &'static str,
3474 code: &str,
3475 offset: usize,
3476 ) -> Location {
3477 (&self.leading_colon, &self.segments).locate_as_group(locator, file_path, code, offset)
3478 }
3479}
3480
3481impl Locate for syn::PathArguments {
3482 fn find_loc(
3483 &self,
3484 locator: &mut LocatorGuard,
3485 file_path: &'static str,
3486 code: &str,
3487 offset: usize,
3488 ) -> Location {
3489 match self {
3490 Self::None => Location {
3491 file_path,
3492 start: offset,
3493 end: offset,
3494 },
3495 Self::AngleBracketed(v) => v.locate(locator, file_path, code, offset),
3496 Self::Parenthesized(v) => v.locate(locator, file_path, code, offset),
3497 }
3498 }
3499}
3500
3501impl Locate for syn::PathSegment {
3502 fn find_loc(
3503 &self,
3504 locator: &mut LocatorGuard,
3505 file_path: &'static str,
3506 code: &str,
3507 offset: usize,
3508 ) -> Location {
3509 (&self.ident, &self.arguments).locate_as_group(locator, file_path, code, offset)
3510 }
3511}
3512
3513impl Locate for syn::PointerMutability {
3514 fn find_loc(
3515 &self,
3516 locator: &mut LocatorGuard,
3517 file_path: &'static str,
3518 code: &str,
3519 offset: usize,
3520 ) -> Location {
3521 match self {
3522 Self::Const(v) => v.locate(locator, file_path, code, offset),
3523 Self::Mut(v) => v.locate(locator, file_path, code, offset),
3524 }
3525 }
3526}
3527
3528impl Locate for syn::PreciseCapture {
3529 fn find_loc(
3530 &self,
3531 locator: &mut LocatorGuard,
3532 file_path: &'static str,
3533 code: &str,
3534 offset: usize,
3535 ) -> Location {
3536 (
3537 &self.use_token,
3538 &self.lt_token,
3539 &self.params,
3540 &self.gt_token,
3541 )
3542 .locate_as_group(locator, file_path, code, offset)
3543 }
3544}
3545
3546impl Locate for syn::PredicateLifetime {
3547 fn find_loc(
3548 &self,
3549 locator: &mut LocatorGuard,
3550 file_path: &'static str,
3551 code: &str,
3552 offset: usize,
3553 ) -> Location {
3554 (&self.lifetime, &self.colon_token, &self.bounds)
3555 .locate_as_group(locator, file_path, code, offset)
3556 }
3557}
3558
3559impl Locate for syn::PredicateType {
3560 fn find_loc(
3561 &self,
3562 locator: &mut LocatorGuard,
3563 file_path: &'static str,
3564 code: &str,
3565 offset: usize,
3566 ) -> Location {
3567 (
3568 &self.lifetimes,
3569 &self.bounded_ty,
3570 &self.colon_token,
3571 &self.bounds,
3572 )
3573 .locate_as_group(locator, file_path, code, offset)
3574 }
3575}
3576
3577impl Locate for syn::QSelf {
3578 fn find_loc(
3579 &self,
3580 locator: &mut LocatorGuard,
3581 file_path: &'static str,
3582 code: &str,
3583 offset: usize,
3584 ) -> Location {
3585 let front_loc = (&self.lt_token, &self.ty, &self.as_token)
3586 .locate_as_group(locator, file_path, code, offset);
3587
3588 const OPEN: char = '<';
3589 const CLOSE: char = '>';
3590
3591 let cur_code = &code[front_loc.end..];
3592
3593 let mut cur = front_loc.end;
3594 let mut level = 1;
3595
3596 for c in cur_code.chars() {
3597 if c == OPEN {
3598 level += 1;
3599 } else if c == CLOSE {
3600 if level == 1 {
3601 break;
3602 }
3603 level -= 1;
3604 }
3605 cur += c.len_utf8();
3606 }
3607
3608 let end = self.gt_token.locate(locator, file_path, code, cur).end;
3609
3610 Location {
3611 file_path,
3612 start: front_loc.start,
3613 end,
3614 }
3615 }
3616}
3617
3618impl Locate for syn::RangeLimits {
3619 fn find_loc(
3620 &self,
3621 locator: &mut LocatorGuard,
3622 file_path: &'static str,
3623 code: &str,
3624 offset: usize,
3625 ) -> Location {
3626 match self {
3627 Self::HalfOpen(v) => v.locate(locator, file_path, code, offset),
3628 Self::Closed(v) => v.locate(locator, file_path, code, offset),
3629 }
3630 }
3631}
3632
3633impl Locate for syn::Receiver {
3634 fn find_loc(
3635 &self,
3636 locator: &mut LocatorGuard,
3637 file_path: &'static str,
3638 code: &str,
3639 offset: usize,
3640 ) -> Location {
3641 if let Some((and_token, reference)) = &self.reference {
3645 if let Some(colon_token) = &self.colon_token {
3646 (
3647 &self.attrs,
3648 and_token,
3649 reference,
3650 &self.mutability,
3651 &self.self_token,
3652 colon_token,
3653 &self.ty,
3654 )
3655 .locate_as_group(locator, file_path, code, offset)
3656 } else {
3657 (
3658 &self.attrs,
3659 and_token,
3660 reference,
3661 &self.mutability,
3662 &self.self_token,
3663 )
3664 .locate_as_group(locator, file_path, code, offset)
3665 }
3666 } else if let Some(colon_token) = &self.colon_token {
3667 (
3668 &self.attrs,
3669 &self.mutability,
3670 &self.self_token,
3671 colon_token,
3672 &self.ty,
3673 )
3674 .locate_as_group(locator, file_path, code, offset)
3675 } else {
3676 (&self.attrs, &self.mutability, &self.self_token)
3677 .locate_as_group(locator, file_path, code, offset)
3678 }
3679 }
3680}
3681
3682impl Locate for syn::ReturnType {
3683 fn find_loc(
3684 &self,
3685 locator: &mut LocatorGuard,
3686 file_path: &'static str,
3687 code: &str,
3688 offset: usize,
3689 ) -> Location {
3690 match self {
3691 Self::Default => Location {
3692 file_path,
3693 start: offset,
3694 end: offset,
3695 },
3696 Self::Type(arrow_token, ty) => {
3697 (arrow_token, ty).locate_as_group(locator, file_path, code, offset)
3698 }
3699 }
3700 }
3701}
3702
3703impl Locate for syn::Signature {
3704 fn find_loc(
3705 &self,
3706 locator: &mut LocatorGuard,
3707 file_path: &'static str,
3708 code: &str,
3709 offset: usize,
3710 ) -> Location {
3711 Surround {
3712 front: (
3713 &self.constness,
3714 &self.asyncness,
3715 &self.unsafety,
3716 &self.abi,
3717 &self.fn_token,
3718 &self.ident,
3719 &self.generics.lt_token,
3721 &self.generics.params,
3722 &self.generics.gt_token,
3723 ),
3724 surround: &self.paren_token,
3725 inner: (&self.inputs, &self.variadic),
3726 back: (&self.output, &self.generics.where_clause),
3727 }
3728 .locate(locator, file_path, code, offset)
3729 }
3730}
3731
3732impl Locate for syn::StaticMutability {
3733 fn find_loc(
3734 &self,
3735 locator: &mut LocatorGuard,
3736 file_path: &'static str,
3737 code: &str,
3738 offset: usize,
3739 ) -> Location {
3740 match self {
3741 Self::Mut(v) => v.locate(locator, file_path, code, offset),
3742 Self::None => Location {
3743 file_path,
3744 start: offset,
3745 end: offset,
3746 },
3747 _ => Location {
3748 file_path,
3749 start: offset,
3750 end: offset,
3751 },
3752 }
3753 }
3754}
3755
3756impl Locate for syn::Stmt {
3757 fn find_loc(
3758 &self,
3759 locator: &mut LocatorGuard,
3760 file_path: &'static str,
3761 code: &str,
3762 offset: usize,
3763 ) -> Location {
3764 match self {
3765 Self::Local(v) => v.locate(locator, file_path, code, offset),
3766 Self::Item(v) => v.locate(locator, file_path, code, offset),
3767 Self::Expr(expr, semi_token) => {
3768 (expr, semi_token).locate_as_group(locator, file_path, code, offset)
3769 }
3770 Self::Macro(v) => v.locate(locator, file_path, code, offset),
3771 }
3772 }
3773}
3774
3775impl Locate for syn::StmtMacro {
3776 fn find_loc(
3777 &self,
3778 locator: &mut LocatorGuard,
3779 file_path: &'static str,
3780 code: &str,
3781 offset: usize,
3782 ) -> Location {
3783 (&self.attrs, &self.mac, &self.semi_token).locate_as_group(locator, file_path, code, offset)
3784 }
3785}
3786
3787impl Locate for syn::TraitBound {
3788 fn find_loc(
3789 &self,
3790 locator: &mut LocatorGuard,
3791 file_path: &'static str,
3792 code: &str,
3793 offset: usize,
3794 ) -> Location {
3795 (&self.modifier, &self.lifetimes, &self.path)
3797 .locate_as_group(locator, file_path, code, offset)
3798 }
3799}
3800
3801impl Locate for syn::TraitBoundModifier {
3802 fn find_loc(
3803 &self,
3804 locator: &mut LocatorGuard,
3805 file_path: &'static str,
3806 code: &str,
3807 offset: usize,
3808 ) -> Location {
3809 match self {
3810 Self::None => Location {
3811 file_path,
3812 start: offset,
3813 end: offset,
3814 },
3815 Self::Maybe(v) => v.locate(locator, file_path, code, offset),
3816 }
3817 }
3818}
3819
3820impl Locate for syn::TraitItem {
3821 fn find_loc(
3822 &self,
3823 locator: &mut LocatorGuard,
3824 file_path: &'static str,
3825 code: &str,
3826 offset: usize,
3827 ) -> Location {
3828 match self {
3829 Self::Const(v) => v.locate(locator, file_path, code, offset),
3830 Self::Fn(v) => v.locate(locator, file_path, code, offset),
3831 Self::Type(v) => v.locate(locator, file_path, code, offset),
3832 Self::Macro(v) => v.locate(locator, file_path, code, offset),
3833 Self::Verbatim(_) => Location {
3834 file_path,
3835 start: offset,
3836 end: offset,
3837 },
3838 _ => Location {
3839 file_path,
3840 start: offset,
3841 end: offset,
3842 },
3843 }
3844 }
3845}
3846
3847impl Locate for syn::TraitItemConst {
3848 fn find_loc(
3849 &self,
3850 locator: &mut LocatorGuard,
3851 file_path: &'static str,
3852 code: &str,
3853 offset: usize,
3854 ) -> Location {
3855 if let Some((eq_token, default)) = &self.default {
3856 (
3857 &self.attrs,
3858 &self.const_token,
3859 &self.ident,
3860 &self.generics,
3861 &self.colon_token,
3862 &self.ty,
3863 eq_token,
3864 default,
3865 &self.semi_token,
3866 )
3867 .locate_as_group(locator, file_path, code, offset)
3868 } else {
3869 (
3870 &self.attrs,
3871 &self.const_token,
3872 &self.ident,
3873 &self.generics,
3874 &self.colon_token,
3875 &self.ty,
3876 &self.semi_token,
3877 )
3878 .locate_as_group(locator, file_path, code, offset)
3879 }
3880 }
3881}
3882
3883impl Locate for syn::TraitItemFn {
3884 fn find_loc(
3885 &self,
3886 locator: &mut LocatorGuard,
3887 file_path: &'static str,
3888 code: &str,
3889 offset: usize,
3890 ) -> Location {
3891 (&self.attrs, &self.sig, &self.default, &self.semi_token)
3892 .locate_as_group(locator, file_path, code, offset)
3893 }
3894}
3895
3896impl Locate for syn::TraitItemType {
3897 fn find_loc(
3898 &self,
3899 locator: &mut LocatorGuard,
3900 file_path: &'static str,
3901 code: &str,
3902 offset: usize,
3903 ) -> Location {
3904 if let Some((eq_token, default)) = &self.default {
3905 (
3906 &self.attrs,
3907 &self.type_token,
3908 &self.ident,
3909 &self.generics,
3910 &self.colon_token,
3911 &self.bounds,
3912 eq_token,
3913 default,
3914 &self.semi_token,
3915 )
3916 .locate_as_group(locator, file_path, code, offset)
3917 } else {
3918 (
3919 &self.attrs,
3920 &self.type_token,
3921 &self.ident,
3922 &self.generics,
3923 &self.colon_token,
3924 &self.bounds,
3925 &self.semi_token,
3926 )
3927 .locate_as_group(locator, file_path, code, offset)
3928 }
3929 }
3930}
3931
3932impl Locate for syn::TraitItemMacro {
3933 fn find_loc(
3934 &self,
3935 locator: &mut LocatorGuard,
3936 file_path: &'static str,
3937 code: &str,
3938 offset: usize,
3939 ) -> Location {
3940 (&self.attrs, &self.mac, &self.semi_token).locate_as_group(locator, file_path, code, offset)
3941 }
3942}
3943
3944impl Locate for syn::Type {
3945 fn find_loc(
3946 &self,
3947 locator: &mut LocatorGuard,
3948 file_path: &'static str,
3949 code: &str,
3950 offset: usize,
3951 ) -> Location {
3952 match self {
3953 Self::Array(v) => v.locate(locator, file_path, code, offset),
3954 Self::BareFn(v) => v.locate(locator, file_path, code, offset),
3955 Self::Group(v) => v.locate(locator, file_path, code, offset),
3956 Self::ImplTrait(v) => v.locate(locator, file_path, code, offset),
3957 Self::Infer(v) => v.locate(locator, file_path, code, offset),
3958 Self::Macro(v) => v.locate(locator, file_path, code, offset),
3959 Self::Never(v) => v.locate(locator, file_path, code, offset),
3960 Self::Paren(v) => v.locate(locator, file_path, code, offset),
3961 Self::Path(v) => v.locate(locator, file_path, code, offset),
3962 Self::Ptr(v) => v.locate(locator, file_path, code, offset),
3963 Self::Reference(v) => v.locate(locator, file_path, code, offset),
3964 Self::Slice(v) => v.locate(locator, file_path, code, offset),
3965 Self::TraitObject(v) => v.locate(locator, file_path, code, offset),
3966 Self::Tuple(v) => v.locate(locator, file_path, code, offset),
3967 Self::Verbatim(_) => Location {
3968 file_path,
3969 start: offset,
3970 end: offset,
3971 },
3972 _ => Location {
3973 file_path,
3974 start: offset,
3975 end: offset,
3976 },
3977 }
3978 }
3979}
3980
3981impl Locate for syn::TypeArray {
3982 fn find_loc(
3983 &self,
3984 locator: &mut LocatorGuard,
3985 file_path: &'static str,
3986 code: &str,
3987 offset: usize,
3988 ) -> Location {
3989 Surround {
3990 front: (),
3991 surround: &self.bracket_token,
3992 inner: (&self.elem, &self.semi_token, &self.len),
3993 back: (),
3994 }
3995 .locate(locator, file_path, code, offset)
3996 }
3997}
3998
3999impl Locate for syn::TypeBareFn {
4000 fn find_loc(
4001 &self,
4002 locator: &mut LocatorGuard,
4003 file_path: &'static str,
4004 code: &str,
4005 offset: usize,
4006 ) -> Location {
4007 Surround {
4008 front: (&self.lifetimes, &self.unsafety, &self.abi, &self.fn_token),
4009 surround: &self.paren_token,
4010 inner: (&self.inputs, &self.variadic),
4011 back: &self.output,
4012 }
4013 .locate(locator, file_path, code, offset)
4014 }
4015}
4016
4017impl Locate for syn::TypeGroup {
4018 fn find_loc(
4019 &self,
4020 locator: &mut LocatorGuard,
4021 file_path: &'static str,
4022 code: &str,
4023 offset: usize,
4024 ) -> Location {
4025 (&self.group_token, &self.elem).locate_as_group(locator, file_path, code, offset)
4026 }
4027}
4028
4029impl Locate for syn::TypeImplTrait {
4030 fn find_loc(
4031 &self,
4032 locator: &mut LocatorGuard,
4033 file_path: &'static str,
4034 code: &str,
4035 offset: usize,
4036 ) -> Location {
4037 (&self.impl_token, &self.bounds).locate_as_group(locator, file_path, code, offset)
4038 }
4039}
4040
4041impl Locate for syn::TypeInfer {
4042 fn find_loc(
4043 &self,
4044 locator: &mut LocatorGuard,
4045 file_path: &'static str,
4046 code: &str,
4047 offset: usize,
4048 ) -> Location {
4049 self.underscore_token
4050 .locate(locator, file_path, code, offset)
4051 }
4052}
4053
4054impl Locate for syn::TypeMacro {
4055 fn find_loc(
4056 &self,
4057 locator: &mut LocatorGuard,
4058 file_path: &'static str,
4059 code: &str,
4060 offset: usize,
4061 ) -> Location {
4062 self.mac.locate(locator, file_path, code, offset)
4063 }
4064}
4065
4066impl Locate for syn::TypeNever {
4067 fn find_loc(
4068 &self,
4069 locator: &mut LocatorGuard,
4070 file_path: &'static str,
4071 code: &str,
4072 offset: usize,
4073 ) -> Location {
4074 self.bang_token.locate(locator, file_path, code, offset)
4075 }
4076}
4077
4078impl Locate for syn::TypeParen {
4079 fn find_loc(
4080 &self,
4081 locator: &mut LocatorGuard,
4082 file_path: &'static str,
4083 code: &str,
4084 offset: usize,
4085 ) -> Location {
4086 Surround {
4087 front: (),
4088 surround: &self.paren_token,
4089 inner: &self.elem,
4090 back: (),
4091 }
4092 .locate(locator, file_path, code, offset)
4093 }
4094}
4095
4096impl Locate for syn::TypePath {
4097 fn find_loc(
4098 &self,
4099 locator: &mut LocatorGuard,
4100 file_path: &'static str,
4101 code: &str,
4102 offset: usize,
4103 ) -> Location {
4104 if let Some(qself) = &self.qself {
4105 Qualified {
4106 front: (),
4107 qself,
4108 path: &self.path,
4109 back: (),
4110 }
4111 .locate(locator, file_path, code, offset)
4112 } else {
4113 self.path.locate(locator, file_path, code, offset)
4114 }
4115 }
4116}
4117
4118impl Locate for syn::TypePtr {
4119 fn find_loc(
4120 &self,
4121 locator: &mut LocatorGuard,
4122 file_path: &'static str,
4123 code: &str,
4124 offset: usize,
4125 ) -> Location {
4126 (
4127 &self.star_token,
4128 &self.const_token,
4129 &self.mutability,
4130 &self.elem,
4131 )
4132 .locate_as_group(locator, file_path, code, offset)
4133 }
4134}
4135
4136impl Locate for syn::TypeReference {
4137 fn find_loc(
4138 &self,
4139 locator: &mut LocatorGuard,
4140 file_path: &'static str,
4141 code: &str,
4142 offset: usize,
4143 ) -> Location {
4144 (
4145 &self.and_token,
4146 &self.lifetime,
4147 &self.mutability,
4148 &self.elem,
4149 )
4150 .locate_as_group(locator, file_path, code, offset)
4151 }
4152}
4153
4154impl Locate for syn::TypeSlice {
4155 fn find_loc(
4156 &self,
4157 locator: &mut LocatorGuard,
4158 file_path: &'static str,
4159 code: &str,
4160 offset: usize,
4161 ) -> Location {
4162 Surround {
4163 front: (),
4164 surround: &self.bracket_token,
4165 inner: &self.elem,
4166 back: (),
4167 }
4168 .locate(locator, file_path, code, offset)
4169 }
4170}
4171
4172impl Locate for syn::TypeTraitObject {
4173 fn find_loc(
4174 &self,
4175 locator: &mut LocatorGuard,
4176 file_path: &'static str,
4177 code: &str,
4178 offset: usize,
4179 ) -> Location {
4180 (&self.dyn_token, &self.bounds).locate_as_group(locator, file_path, code, offset)
4181 }
4182}
4183
4184impl Locate for syn::TypeTuple {
4185 fn find_loc(
4186 &self,
4187 locator: &mut LocatorGuard,
4188 file_path: &'static str,
4189 code: &str,
4190 offset: usize,
4191 ) -> Location {
4192 Surround {
4193 front: (),
4194 surround: &self.paren_token,
4195 inner: &self.elems,
4196 back: (),
4197 }
4198 .locate(locator, file_path, code, offset)
4199 }
4200}
4201
4202impl Locate for syn::TypeParam {
4203 fn find_loc(
4204 &self,
4205 locator: &mut LocatorGuard,
4206 file_path: &'static str,
4207 code: &str,
4208 offset: usize,
4209 ) -> Location {
4210 (
4211 &self.attrs,
4212 &self.ident,
4213 &self.colon_token,
4214 &self.bounds,
4215 &self.eq_token,
4216 &self.default,
4217 )
4218 .locate_as_group(locator, file_path, code, offset)
4219 }
4220}
4221
4222impl Locate for syn::TypeParamBound {
4223 fn find_loc(
4224 &self,
4225 locator: &mut LocatorGuard,
4226 file_path: &'static str,
4227 code: &str,
4228 offset: usize,
4229 ) -> Location {
4230 match self {
4231 Self::Trait(v) => v.locate(locator, file_path, code, offset),
4232 Self::Lifetime(v) => v.locate(locator, file_path, code, offset),
4233 Self::PreciseCapture(v) => v.locate(locator, file_path, code, offset),
4234 Self::Verbatim(_) => Location {
4235 file_path,
4236 start: offset,
4237 end: offset,
4238 },
4239 _ => Location {
4240 file_path,
4241 start: offset,
4242 end: offset,
4243 },
4244 }
4245 }
4246}
4247
4248impl Locate for syn::UnOp {
4249 fn find_loc(
4250 &self,
4251 locator: &mut LocatorGuard,
4252 file_path: &'static str,
4253 code: &str,
4254 offset: usize,
4255 ) -> Location {
4256 match self {
4257 Self::Deref(v) => v.locate(locator, file_path, code, offset),
4258 Self::Not(v) => v.locate(locator, file_path, code, offset),
4259 Self::Neg(v) => v.locate(locator, file_path, code, offset),
4260 _ => Location {
4261 file_path,
4262 start: offset,
4263 end: offset,
4264 },
4265 }
4266 }
4267}
4268
4269impl Locate for syn::UseGlob {
4270 fn find_loc(
4271 &self,
4272 locator: &mut LocatorGuard,
4273 file_path: &'static str,
4274 code: &str,
4275 offset: usize,
4276 ) -> Location {
4277 self.star_token.locate(locator, file_path, code, offset)
4278 }
4279}
4280
4281impl Locate for syn::UseGroup {
4282 fn find_loc(
4283 &self,
4284 locator: &mut LocatorGuard,
4285 file_path: &'static str,
4286 code: &str,
4287 offset: usize,
4288 ) -> Location {
4289 Surround {
4290 front: (),
4291 surround: &self.brace_token,
4292 inner: &self.items,
4293 back: (),
4294 }
4295 .locate(locator, file_path, code, offset)
4296 }
4297}
4298
4299impl Locate for syn::UseName {
4300 fn find_loc(
4301 &self,
4302 locator: &mut LocatorGuard,
4303 file_path: &'static str,
4304 code: &str,
4305 offset: usize,
4306 ) -> Location {
4307 self.ident.locate(locator, file_path, code, offset)
4308 }
4309}
4310
4311impl Locate for syn::UsePath {
4312 fn find_loc(
4313 &self,
4314 locator: &mut LocatorGuard,
4315 file_path: &'static str,
4316 code: &str,
4317 offset: usize,
4318 ) -> Location {
4319 (&self.ident, &self.colon2_token, &self.tree)
4320 .locate_as_group(locator, file_path, code, offset)
4321 }
4322}
4323
4324impl Locate for syn::UseRename {
4325 fn find_loc(
4326 &self,
4327 locator: &mut LocatorGuard,
4328 file_path: &'static str,
4329 code: &str,
4330 offset: usize,
4331 ) -> Location {
4332 (&self.ident, &self.as_token, &self.rename)
4333 .locate_as_group(locator, file_path, code, offset)
4334 }
4335}
4336
4337impl Locate for syn::UseTree {
4338 fn find_loc(
4339 &self,
4340 locator: &mut LocatorGuard,
4341 file_path: &'static str,
4342 code: &str,
4343 offset: usize,
4344 ) -> Location {
4345 match self {
4346 Self::Path(v) => v.locate(locator, file_path, code, offset),
4347 Self::Name(v) => v.locate(locator, file_path, code, offset),
4348 Self::Rename(v) => v.locate(locator, file_path, code, offset),
4349 Self::Glob(v) => v.locate(locator, file_path, code, offset),
4350 Self::Group(v) => v.locate(locator, file_path, code, offset),
4351 }
4352 }
4353}
4354
4355impl Locate for syn::Variadic {
4356 fn find_loc(
4357 &self,
4358 locator: &mut LocatorGuard,
4359 file_path: &'static str,
4360 code: &str,
4361 offset: usize,
4362 ) -> Location {
4363 if let Some((pat, colon_token)) = &self.pat {
4364 (&self.attrs, pat, colon_token, &self.dots, &self.comma)
4365 .locate_as_group(locator, file_path, code, offset)
4366 } else {
4367 (&self.attrs, &self.dots, &self.comma).locate_as_group(locator, file_path, code, offset)
4368 }
4369 }
4370}
4371
4372impl Locate for syn::Variant {
4373 fn find_loc(
4374 &self,
4375 locator: &mut LocatorGuard,
4376 file_path: &'static str,
4377 code: &str,
4378 offset: usize,
4379 ) -> Location {
4380 if let Some((eq_token, discriminant)) = &self.discriminant {
4381 (
4382 &self.attrs,
4383 &self.ident,
4384 &self.fields,
4385 eq_token,
4386 discriminant,
4387 )
4388 .locate_as_group(locator, file_path, code, offset)
4389 } else {
4390 (&self.attrs, &self.ident, &self.fields)
4391 .locate_as_group(locator, file_path, code, offset)
4392 }
4393 }
4394}
4395
4396impl Locate for syn::Visibility {
4397 fn find_loc(
4398 &self,
4399 locator: &mut LocatorGuard,
4400 file_path: &'static str,
4401 code: &str,
4402 offset: usize,
4403 ) -> Location {
4404 match self {
4405 Self::Public(v) => v.locate(locator, file_path, code, offset),
4406 Self::Restricted(v) => v.locate(locator, file_path, code, offset),
4407 Self::Inherited => Location {
4408 file_path,
4409 start: offset,
4410 end: offset,
4411 },
4412 }
4413 }
4414}
4415
4416impl Locate for syn::VisRestricted {
4417 fn find_loc(
4418 &self,
4419 locator: &mut LocatorGuard,
4420 file_path: &'static str,
4421 code: &str,
4422 offset: usize,
4423 ) -> Location {
4424 Surround {
4425 front: &self.pub_token,
4426 surround: &self.paren_token,
4427 inner: (&self.in_token, &self.path),
4428 back: (),
4429 }
4430 .locate(locator, file_path, code, offset)
4431 }
4432}
4433
4434impl Locate for syn::WhereClause {
4435 fn find_loc(
4436 &self,
4437 locator: &mut LocatorGuard,
4438 file_path: &'static str,
4439 code: &str,
4440 offset: usize,
4441 ) -> Location {
4442 (&self.where_token, &self.predicates).locate_as_group(locator, file_path, code, offset)
4443 }
4444}
4445
4446impl Locate for syn::WherePredicate {
4447 fn find_loc(
4448 &self,
4449 locator: &mut LocatorGuard,
4450 file_path: &'static str,
4451 code: &str,
4452 offset: usize,
4453 ) -> Location {
4454 match self {
4455 Self::Lifetime(v) => v.locate(locator, file_path, code, offset),
4456 Self::Type(v) => v.locate(locator, file_path, code, offset),
4457 _ => Location {
4458 file_path,
4459 start: offset,
4460 end: offset,
4461 },
4462 }
4463 }
4464}
4465
4466impl<T: Locate> Locate for Option<T> {
4469 fn find_loc(
4470 &self,
4471 locator: &mut LocatorGuard,
4472 file_path: &'static str,
4473 code: &str,
4474 offset: usize,
4475 ) -> Location {
4476 if let Some(inner) = self {
4477 inner.locate(locator, file_path, code, offset)
4478 } else {
4479 Location {
4480 file_path,
4481 start: offset,
4482 end: offset,
4483 }
4484 }
4485 }
4486}
4487
4488impl<T: Locate> Locate for Box<T> {
4489 fn find_loc(
4490 &self,
4491 locator: &mut LocatorGuard,
4492 file_path: &'static str,
4493 code: &str,
4494 offset: usize,
4495 ) -> Location {
4496 let t = &**self;
4497 t.locate(locator, file_path, code, offset)
4498 }
4499}
4500
4501impl<T: Locate> Locate for Vec<T> {
4502 fn find_loc(
4503 &self,
4504 locator: &mut LocatorGuard,
4505 file_path: &'static str,
4506 code: &str,
4507 offset: usize,
4508 ) -> Location {
4509 let mut start = usize::MAX;
4510 let mut end = offset;
4511
4512 for item in self {
4513 let loc = item.locate(locator, file_path, code, end);
4514 start = start.min(loc.start);
4515 end = loc.end;
4516 }
4517
4518 Location {
4519 file_path,
4520 start: if start != usize::MAX { start } else { offset },
4521 end,
4522 }
4523 }
4524}
4525
4526impl<T, S> Locate for syn::punctuated::Punctuated<T, S>
4527where
4528 T: Locate,
4529 S: Locate,
4530{
4531 fn find_loc(
4532 &self,
4533 locator: &mut LocatorGuard,
4534 file_path: &'static str,
4535 code: &str,
4536 offset: usize,
4537 ) -> Location {
4538 let mut start = usize::MAX;
4539 let mut end = offset;
4540
4541 for item in self {
4542 let loc = item.locate(locator, file_path, code, end);
4543 start = start.min(loc.start);
4544 end = loc.end;
4545 }
4546
4547 Location {
4548 file_path,
4549 start: if start != usize::MAX { start } else { offset },
4550 end,
4551 }
4552 }
4553}
4554
4555pub mod helper {
4558 use super::*;
4559
4560 pub fn char_location(
4561 file_path: &'static str,
4562 code: &str,
4563 offset: usize,
4564 content: char,
4565 ) -> Location {
4566 let cur_code = &code[offset..];
4567 let start = offset
4568 + cur_code
4569 .find(content)
4570 .unwrap_or_else(|| panic!("expected `{content}` from `{cur_code}`"));
4571
4572 Location {
4573 file_path,
4574 start,
4575 end: start + content.len_utf8(),
4576 }
4577 }
4578
4579 pub fn str_location(
4580 file_path: &'static str,
4581 code: &str,
4582 offset: usize,
4583 content: &str,
4584 ) -> Location {
4585 let cur_code = &code[offset..];
4586
4587 let start = offset
4588 + cur_code
4589 .find(content)
4590 .unwrap_or_else(|| panic!("expected `{content}` from `{cur_code}`"));
4591
4592 Location {
4593 file_path,
4594 start,
4595 end: start + content.len(),
4596 }
4597 }
4598}