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 let loc = 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 let start = locator.get_location(&self.generics.lt_token).unwrap().start;
2632 let end = locator
2633 .get_location(&self.generics.where_clause)
2634 .unwrap()
2635 .end;
2636 locator.set_location(
2637 &self.generics,
2638 Location {
2639 file_path,
2640 start,
2641 end,
2642 },
2643 );
2644
2645 loc
2646 }
2647}
2648
2649impl Locate for syn::ItemMacro {
2652 fn find_loc(
2653 &self,
2654 locator: &mut LocatorGuard,
2655 file_path: &'static str,
2656 code: &str,
2657 offset: usize,
2658 ) -> Location {
2659 Surround {
2660 front: (
2661 &self.attrs,
2662 &self.mac.path,
2663 &self.mac.bang_token,
2664 &self.ident,
2665 ),
2666 surround: &self.mac.delimiter,
2667 inner: (), back: &self.semi_token,
2669 }
2670 .locate(locator, file_path, code, offset)
2671 }
2672}
2673
2674impl Locate for syn::ItemMod {
2675 fn find_loc(
2676 &self,
2677 locator: &mut LocatorGuard,
2678 file_path: &'static str,
2679 code: &str,
2680 offset: usize,
2681 ) -> Location {
2682 match (&self.content, &self.semi) {
2683 (Some((brace, items)), Some(semi_token)) => Surround {
2684 front: (&self.attrs, &self.vis, &self.mod_token, &self.ident),
2685 surround: brace,
2686 inner: items,
2687 back: semi_token,
2688 }
2689 .locate(locator, file_path, code, offset),
2690 (Some((brace, items)), None) => Surround {
2691 front: (&self.attrs, &self.vis, &self.mod_token, &self.ident),
2692 surround: brace,
2693 inner: items,
2694 back: (),
2695 }
2696 .locate(locator, file_path, code, offset),
2697 (None, Some(semi_token)) => (
2698 &self.attrs,
2699 &self.vis,
2700 &self.mod_token,
2701 &self.ident,
2702 semi_token,
2703 )
2704 .locate_as_group(locator, file_path, code, offset),
2705 (None, None) => (&self.attrs, &self.vis, &self.mod_token, &self.ident)
2706 .locate_as_group(locator, file_path, code, offset),
2707 }
2708 }
2709}
2710
2711impl Locate for syn::ItemStatic {
2712 fn find_loc(
2713 &self,
2714 locator: &mut LocatorGuard,
2715 file_path: &'static str,
2716 code: &str,
2717 offset: usize,
2718 ) -> Location {
2719 (
2720 &self.attrs,
2721 &self.vis,
2722 &self.static_token,
2723 &self.mutability,
2724 &self.ident,
2725 &self.colon_token,
2726 &self.ty,
2727 &self.eq_token,
2728 &self.expr,
2729 &self.semi_token,
2730 )
2731 .locate_as_group(locator, file_path, code, offset)
2732 }
2733}
2734
2735impl Locate for syn::ItemStruct {
2736 fn find_loc(
2737 &self,
2738 locator: &mut LocatorGuard,
2739 file_path: &'static str,
2740 code: &str,
2741 offset: usize,
2742 ) -> Location {
2743 (
2744 &self.attrs,
2745 &self.vis,
2746 &self.struct_token,
2747 &self.ident,
2748 &self.generics,
2749 &self.fields,
2750 &self.semi_token,
2751 )
2752 .locate_as_group(locator, file_path, code, offset)
2753 }
2754}
2755
2756impl Locate for syn::ItemTrait {
2757 fn find_loc(
2758 &self,
2759 locator: &mut LocatorGuard,
2760 file_path: &'static str,
2761 code: &str,
2762 offset: usize,
2763 ) -> Location {
2764 Surround {
2765 front: (
2766 &self.attrs,
2767 &self.vis,
2768 &self.unsafety,
2769 &self.auto_token,
2770 &self.restriction,
2771 &self.trait_token,
2772 &self.ident,
2773 &self.generics,
2774 &self.colon_token,
2775 &self.supertraits,
2776 ),
2777 surround: &self.brace_token,
2778 inner: &self.items,
2779 back: (),
2780 }
2781 .locate(locator, file_path, code, offset)
2782 }
2783}
2784
2785impl Locate for syn::ItemTraitAlias {
2786 fn find_loc(
2787 &self,
2788 locator: &mut LocatorGuard,
2789 file_path: &'static str,
2790 code: &str,
2791 offset: usize,
2792 ) -> Location {
2793 (
2794 &self.attrs,
2795 &self.vis,
2796 &self.trait_token,
2797 &self.ident,
2798 &self.generics,
2799 &self.eq_token,
2800 &self.bounds,
2801 &self.semi_token,
2802 )
2803 .locate_as_group(locator, file_path, code, offset)
2804 }
2805}
2806
2807impl Locate for syn::ItemType {
2808 fn find_loc(
2809 &self,
2810 locator: &mut LocatorGuard,
2811 file_path: &'static str,
2812 code: &str,
2813 offset: usize,
2814 ) -> Location {
2815 (
2816 &self.attrs,
2817 &self.vis,
2818 &self.type_token,
2819 &self.ident,
2820 &self.generics,
2821 &self.eq_token,
2822 &self.ty,
2823 &self.semi_token,
2824 )
2825 .locate_as_group(locator, file_path, code, offset)
2826 }
2827}
2828
2829impl Locate for syn::ItemUnion {
2830 fn find_loc(
2831 &self,
2832 locator: &mut LocatorGuard,
2833 file_path: &'static str,
2834 code: &str,
2835 offset: usize,
2836 ) -> Location {
2837 (
2838 &self.attrs,
2839 &self.vis,
2840 &self.union_token,
2841 &self.ident,
2842 &self.generics,
2843 &self.fields,
2844 )
2845 .locate_as_group(locator, file_path, code, offset)
2846 }
2847}
2848
2849impl Locate for syn::ItemUse {
2850 fn find_loc(
2851 &self,
2852 locator: &mut LocatorGuard,
2853 file_path: &'static str,
2854 code: &str,
2855 offset: usize,
2856 ) -> Location {
2857 (
2858 &self.attrs,
2859 &self.vis,
2860 &self.use_token,
2861 &self.leading_colon,
2862 &self.tree,
2863 &self.semi_token,
2864 )
2865 .locate_as_group(locator, file_path, code, offset)
2866 }
2867}
2868
2869impl Locate for syn::Label {
2870 fn find_loc(
2871 &self,
2872 locator: &mut LocatorGuard,
2873 file_path: &'static str,
2874 code: &str,
2875 offset: usize,
2876 ) -> Location {
2877 (&self.name, &self.colon_token).locate_as_group(locator, file_path, code, offset)
2878 }
2879}
2880
2881impl Locate for syn::Lifetime {
2882 fn find_loc(
2883 &self,
2884 locator: &mut LocatorGuard,
2885 file_path: &'static str,
2886 code: &str,
2887 offset: usize,
2888 ) -> Location {
2889 let cur_code = &code[offset..];
2890
2891 let start = offset
2892 + cur_code
2893 .find('\'')
2894 .unwrap_or_else(|| panic!("expected ' from {cur_code}"));
2895 let end = self.ident.locate(locator, file_path, code, start + 1).end;
2896
2897 Location {
2898 file_path,
2899 start,
2900 end,
2901 }
2902 }
2903}
2904
2905impl Locate for syn::LifetimeParam {
2906 fn find_loc(
2907 &self,
2908 locator: &mut LocatorGuard,
2909 file_path: &'static str,
2910 code: &str,
2911 offset: usize,
2912 ) -> Location {
2913 (&self.attrs, &self.lifetime, &self.colon_token, &self.bounds)
2914 .locate_as_group(locator, file_path, code, offset)
2915 }
2916}
2917
2918impl Locate for syn::Lit {
2919 fn find_loc(
2920 &self,
2921 locator: &mut LocatorGuard,
2922 file_path: &'static str,
2923 code: &str,
2924 offset: usize,
2925 ) -> Location {
2926 match self {
2927 Self::Str(v) => v.locate(locator, file_path, code, offset),
2928 Self::ByteStr(v) => v.locate(locator, file_path, code, offset),
2929 Self::CStr(v) => v.locate(locator, file_path, code, offset),
2930 Self::Byte(v) => v.locate(locator, file_path, code, offset),
2931 Self::Char(v) => v.locate(locator, file_path, code, offset),
2932 Self::Int(v) => v.locate(locator, file_path, code, offset),
2933 Self::Float(v) => v.locate(locator, file_path, code, offset),
2934 Self::Bool(v) => v.locate(locator, file_path, code, offset),
2935 Self::Verbatim(_) => Location {
2936 file_path,
2937 start: offset,
2938 end: offset,
2939 },
2940 _ => Location {
2941 file_path,
2942 start: offset,
2943 end: offset,
2944 },
2945 }
2946 }
2947}
2948
2949impl Locate for syn::LitStr {
2950 fn find_loc(
2951 &self,
2952 _: &mut LocatorGuard,
2953 file_path: &'static str,
2954 code: &str,
2955 offset: usize,
2956 ) -> Location {
2957 let lit = self.token().to_string();
2958 helper::str_location(file_path, code, offset, &lit)
2959 }
2960}
2961
2962impl Locate for syn::LitByteStr {
2963 fn find_loc(
2964 &self,
2965 _: &mut LocatorGuard,
2966 file_path: &'static str,
2967 code: &str,
2968 offset: usize,
2969 ) -> Location {
2970 let lit = self.token().to_string();
2971 helper::str_location(file_path, code, offset, &lit)
2972 }
2973}
2974
2975impl Locate for syn::LitCStr {
2976 fn find_loc(
2977 &self,
2978 _: &mut LocatorGuard,
2979 file_path: &'static str,
2980 code: &str,
2981 offset: usize,
2982 ) -> Location {
2983 let lit = self.token().to_string();
2984 helper::str_location(file_path, code, offset, &lit)
2985 }
2986}
2987
2988impl Locate for syn::LitByte {
2989 fn find_loc(
2990 &self,
2991 _: &mut LocatorGuard,
2992 file_path: &'static str,
2993 code: &str,
2994 offset: usize,
2995 ) -> Location {
2996 let lit = self.token().to_string();
2997 helper::str_location(file_path, code, offset, &lit)
2998 }
2999}
3000
3001impl Locate for syn::LitChar {
3002 fn find_loc(
3003 &self,
3004 _: &mut LocatorGuard,
3005 file_path: &'static str,
3006 code: &str,
3007 offset: usize,
3008 ) -> Location {
3009 let lit = self.token().to_string();
3010 helper::str_location(file_path, code, offset, &lit)
3011 }
3012}
3013
3014impl Locate for syn::LitInt {
3015 fn find_loc(
3016 &self,
3017 _: &mut LocatorGuard,
3018 file_path: &'static str,
3019 code: &str,
3020 offset: usize,
3021 ) -> Location {
3022 let lit = self.token().to_string();
3023 helper::str_location(file_path, code, offset, &lit)
3024 }
3025}
3026
3027impl Locate for syn::LitFloat {
3028 fn find_loc(
3029 &self,
3030 _: &mut LocatorGuard,
3031 file_path: &'static str,
3032 code: &str,
3033 offset: usize,
3034 ) -> Location {
3035 let lit = self.token().to_string();
3036 helper::str_location(file_path, code, offset, &lit)
3037 }
3038}
3039
3040impl Locate for syn::LitBool {
3041 fn find_loc(
3042 &self,
3043 _: &mut LocatorGuard,
3044 file_path: &'static str,
3045 code: &str,
3046 offset: usize,
3047 ) -> Location {
3048 let lit = self.token().to_string();
3049 helper::str_location(file_path, code, offset, &lit)
3050 }
3051}
3052
3053impl Locate for syn::Local {
3054 fn find_loc(
3055 &self,
3056 locator: &mut LocatorGuard,
3057 file_path: &'static str,
3058 code: &str,
3059 offset: usize,
3060 ) -> Location {
3061 (
3062 &self.attrs,
3063 &self.let_token,
3064 &self.pat,
3065 &self.init,
3066 &self.semi_token,
3067 )
3068 .locate_as_group(locator, file_path, code, offset)
3069 }
3070}
3071
3072impl Locate for syn::LocalInit {
3073 fn find_loc(
3074 &self,
3075 locator: &mut LocatorGuard,
3076 file_path: &'static str,
3077 code: &str,
3078 offset: usize,
3079 ) -> Location {
3080 if let Some((else_token, diverge)) = &self.diverge {
3081 (&self.eq_token, &self.expr, else_token, diverge)
3082 .locate_as_group(locator, file_path, code, offset)
3083 } else {
3084 (&self.eq_token, &self.expr).locate_as_group(locator, file_path, code, offset)
3085 }
3086 }
3087}
3088
3089impl Locate for syn::Macro {
3090 fn find_loc(
3091 &self,
3092 locator: &mut LocatorGuard,
3093 file_path: &'static str,
3094 code: &str,
3095 offset: usize,
3096 ) -> Location {
3097 match &self.delimiter {
3098 syn::MacroDelimiter::Paren(paren) => Surround {
3099 front: (&self.path, &self.bang_token),
3100 surround: paren,
3101 inner: (),
3102 back: (),
3103 }
3104 .locate(locator, file_path, code, offset),
3105 syn::MacroDelimiter::Brace(brace) => Surround {
3106 front: (&self.path, &self.bang_token),
3107 surround: brace,
3108 inner: (),
3109 back: (),
3110 }
3111 .locate(locator, file_path, code, offset),
3112 syn::MacroDelimiter::Bracket(bracket) => Surround {
3113 front: (&self.path, &self.bang_token),
3114 surround: bracket,
3115 inner: (),
3116 back: (),
3117 }
3118 .locate(locator, file_path, code, offset),
3119 }
3120 }
3121}
3122
3123impl Locate for syn::MacroDelimiter {
3124 fn find_loc(
3125 &self,
3126 locator: &mut LocatorGuard,
3127 file_path: &'static str,
3128 code: &str,
3129 offset: usize,
3130 ) -> Location {
3131 match self {
3132 Self::Paren(v) => v.locate(locator, file_path, code, offset),
3133 Self::Brace(v) => v.locate(locator, file_path, code, offset),
3134 Self::Bracket(v) => v.locate(locator, file_path, code, offset),
3135 }
3136 }
3137}
3138
3139impl Locate for syn::Member {
3140 fn find_loc(
3141 &self,
3142 locator: &mut LocatorGuard,
3143 file_path: &'static str,
3144 code: &str,
3145 offset: usize,
3146 ) -> Location {
3147 match self {
3148 Self::Named(v) => v.locate(locator, file_path, code, offset),
3149 Self::Unnamed(v) => v.locate(locator, file_path, code, offset),
3150 }
3151 }
3152}
3153
3154impl Locate for syn::Meta {
3155 fn find_loc(
3156 &self,
3157 locator: &mut LocatorGuard,
3158 file_path: &'static str,
3159 code: &str,
3160 offset: usize,
3161 ) -> Location {
3162 match self {
3163 Self::Path(v) => v.locate(locator, file_path, code, offset),
3164 Self::List(v) => v.locate(locator, file_path, code, offset),
3165 Self::NameValue(v) => v.locate(locator, file_path, code, offset),
3166 }
3167 }
3168}
3169
3170impl Locate for syn::MetaList {
3171 fn find_loc(
3172 &self,
3173 locator: &mut LocatorGuard,
3174 file_path: &'static str,
3175 code: &str,
3176 offset: usize,
3177 ) -> Location {
3178 match &self.delimiter {
3179 syn::MacroDelimiter::Paren(paren) => Surround {
3180 front: &self.path,
3181 surround: paren,
3182 inner: (),
3183 back: (),
3184 }
3185 .locate(locator, file_path, code, offset),
3186 syn::MacroDelimiter::Brace(brace) => Surround {
3187 front: &self.path,
3188 surround: brace,
3189 inner: (),
3190 back: (),
3191 }
3192 .locate(locator, file_path, code, offset),
3193 syn::MacroDelimiter::Bracket(bracket) => Surround {
3194 front: &self.path,
3195 surround: bracket,
3196 inner: (),
3197 back: (),
3198 }
3199 .locate(locator, file_path, code, offset),
3200 }
3201 }
3202}
3203
3204impl Locate for syn::MetaNameValue {
3205 fn find_loc(
3206 &self,
3207 locator: &mut LocatorGuard,
3208 file_path: &'static str,
3209 code: &str,
3210 offset: usize,
3211 ) -> Location {
3212 (&self.path, &self.eq_token, &self.value).locate_as_group(locator, file_path, code, offset)
3213 }
3214}
3215
3216impl Locate for syn::ParenthesizedGenericArguments {
3217 fn find_loc(
3218 &self,
3219 locator: &mut LocatorGuard,
3220 file_path: &'static str,
3221 code: &str,
3222 offset: usize,
3223 ) -> Location {
3224 Surround {
3225 front: (),
3226 surround: &self.paren_token,
3227 inner: &self.inputs,
3228 back: &self.output,
3229 }
3230 .locate(locator, file_path, code, offset)
3231 }
3232}
3233
3234impl Locate for syn::Pat {
3235 fn find_loc(
3236 &self,
3237 locator: &mut LocatorGuard,
3238 file_path: &'static str,
3239 code: &str,
3240 offset: usize,
3241 ) -> Location {
3242 match self {
3243 Self::Const(v) => v.locate(locator, file_path, code, offset),
3244 Self::Ident(v) => v.locate(locator, file_path, code, offset),
3245 Self::Lit(v) => v.locate(locator, file_path, code, offset),
3246 Self::Macro(v) => v.locate(locator, file_path, code, offset),
3247 Self::Or(v) => v.locate(locator, file_path, code, offset),
3248 Self::Paren(v) => v.locate(locator, file_path, code, offset),
3249 Self::Path(v) => v.locate(locator, file_path, code, offset),
3250 Self::Range(v) => v.locate(locator, file_path, code, offset),
3251 Self::Reference(v) => v.locate(locator, file_path, code, offset),
3252 Self::Rest(v) => v.locate(locator, file_path, code, offset),
3253 Self::Slice(v) => v.locate(locator, file_path, code, offset),
3254 Self::Struct(v) => v.locate(locator, file_path, code, offset),
3255 Self::Tuple(v) => v.locate(locator, file_path, code, offset),
3256 Self::TupleStruct(v) => v.locate(locator, file_path, code, offset),
3257 Self::Type(v) => v.locate(locator, file_path, code, offset),
3258 Self::Verbatim(_) => Location {
3259 file_path,
3260 start: offset,
3261 end: offset,
3262 },
3263 Self::Wild(v) => v.locate(locator, file_path, code, offset),
3264 _ => Location {
3265 file_path,
3266 start: offset,
3267 end: offset,
3268 },
3269 }
3270 }
3271}
3272
3273impl Locate for syn::PatIdent {
3274 fn find_loc(
3275 &self,
3276 locator: &mut LocatorGuard,
3277 file_path: &'static str,
3278 code: &str,
3279 offset: usize,
3280 ) -> Location {
3281 if let Some((at_token, subpat)) = &self.subpat {
3282 (
3283 &self.attrs,
3284 &self.by_ref,
3285 &self.mutability,
3286 &self.ident,
3287 at_token,
3288 subpat,
3289 )
3290 .locate_as_group(locator, file_path, code, offset)
3291 } else {
3292 (&self.attrs, &self.by_ref, &self.mutability, &self.ident)
3293 .locate_as_group(locator, file_path, code, offset)
3294 }
3295 }
3296}
3297
3298impl Locate for syn::PatOr {
3299 fn find_loc(
3300 &self,
3301 locator: &mut LocatorGuard,
3302 file_path: &'static str,
3303 code: &str,
3304 offset: usize,
3305 ) -> Location {
3306 (&self.attrs, &self.leading_vert, &self.cases)
3307 .locate_as_group(locator, file_path, code, offset)
3308 }
3309}
3310
3311impl Locate for syn::PatParen {
3312 fn find_loc(
3313 &self,
3314 locator: &mut LocatorGuard,
3315 file_path: &'static str,
3316 code: &str,
3317 offset: usize,
3318 ) -> Location {
3319 Surround {
3320 front: &self.attrs,
3321 surround: &self.paren_token,
3322 inner: &self.pat,
3323 back: (),
3324 }
3325 .locate(locator, file_path, code, offset)
3326 }
3327}
3328
3329impl Locate for syn::PatReference {
3330 fn find_loc(
3331 &self,
3332 locator: &mut LocatorGuard,
3333 file_path: &'static str,
3334 code: &str,
3335 offset: usize,
3336 ) -> Location {
3337 (&self.attrs, &self.and_token, &self.mutability, &self.pat)
3338 .locate_as_group(locator, file_path, code, offset)
3339 }
3340}
3341
3342impl Locate for syn::PatRest {
3343 fn find_loc(
3344 &self,
3345 locator: &mut LocatorGuard,
3346 file_path: &'static str,
3347 code: &str,
3348 offset: usize,
3349 ) -> Location {
3350 (&self.attrs, &self.dot2_token).locate_as_group(locator, file_path, code, offset)
3351 }
3352}
3353
3354impl Locate for syn::PatSlice {
3355 fn find_loc(
3356 &self,
3357 locator: &mut LocatorGuard,
3358 file_path: &'static str,
3359 code: &str,
3360 offset: usize,
3361 ) -> Location {
3362 Surround {
3363 front: &self.attrs,
3364 surround: &self.bracket_token,
3365 inner: &self.elems,
3366 back: (),
3367 }
3368 .locate(locator, file_path, code, offset)
3369 }
3370}
3371
3372impl Locate for syn::PatStruct {
3373 fn find_loc(
3374 &self,
3375 locator: &mut LocatorGuard,
3376 file_path: &'static str,
3377 code: &str,
3378 offset: usize,
3379 ) -> Location {
3380 let front_loc = if let Some(qself) = &self.qself {
3381 Qualified {
3382 front: &self.attrs,
3383 qself,
3384 path: &self.path,
3385 back: (),
3386 }
3387 .locate(locator, file_path, code, offset)
3388 } else {
3389 (&self.attrs, &self.path).locate_as_group(locator, file_path, code, offset)
3390 };
3391
3392 let back_loc = Surround {
3393 front: (),
3394 surround: &self.brace_token,
3395 inner: (&self.fields, &self.rest),
3396 back: (),
3397 }
3398 .locate(locator, file_path, code, front_loc.end);
3399
3400 Location {
3401 file_path,
3402 start: front_loc.start,
3403 end: back_loc.end,
3404 }
3405 }
3406}
3407
3408impl Locate for syn::PatTuple {
3409 fn find_loc(
3410 &self,
3411 locator: &mut LocatorGuard,
3412 file_path: &'static str,
3413 code: &str,
3414 offset: usize,
3415 ) -> Location {
3416 Surround {
3417 front: &self.attrs,
3418 surround: &self.paren_token,
3419 inner: &self.elems,
3420 back: (),
3421 }
3422 .locate(locator, file_path, code, offset)
3423 }
3424}
3425
3426impl Locate for syn::PatTupleStruct {
3427 fn find_loc(
3428 &self,
3429 locator: &mut LocatorGuard,
3430 file_path: &'static str,
3431 code: &str,
3432 offset: usize,
3433 ) -> Location {
3434 let front_loc = if let Some(qself) = &self.qself {
3435 Qualified {
3436 front: &self.attrs,
3437 qself,
3438 path: &self.path,
3439 back: (),
3440 }
3441 .locate(locator, file_path, code, offset)
3442 } else {
3443 (&self.attrs, &self.path).locate_as_group(locator, file_path, code, offset)
3444 };
3445
3446 let back_loc = Surround {
3447 front: (),
3448 surround: &self.paren_token,
3449 inner: &self.elems,
3450 back: (),
3451 }
3452 .locate(locator, file_path, code, front_loc.end);
3453
3454 Location {
3455 file_path,
3456 start: front_loc.start,
3457 end: back_loc.end,
3458 }
3459 }
3460}
3461
3462impl Locate for syn::PatType {
3463 fn find_loc(
3464 &self,
3465 locator: &mut LocatorGuard,
3466 file_path: &'static str,
3467 code: &str,
3468 offset: usize,
3469 ) -> Location {
3470 (&self.attrs, &self.pat, &self.colon_token, &self.ty)
3471 .locate_as_group(locator, file_path, code, offset)
3472 }
3473}
3474
3475impl Locate for syn::PatWild {
3476 fn find_loc(
3477 &self,
3478 locator: &mut LocatorGuard,
3479 file_path: &'static str,
3480 code: &str,
3481 offset: usize,
3482 ) -> Location {
3483 (&self.attrs, &self.underscore_token).locate_as_group(locator, file_path, code, offset)
3484 }
3485}
3486
3487impl Locate for syn::Path {
3488 fn find_loc(
3489 &self,
3490 locator: &mut LocatorGuard,
3491 file_path: &'static str,
3492 code: &str,
3493 offset: usize,
3494 ) -> Location {
3495 (&self.leading_colon, &self.segments).locate_as_group(locator, file_path, code, offset)
3496 }
3497}
3498
3499impl Locate for syn::PathArguments {
3500 fn find_loc(
3501 &self,
3502 locator: &mut LocatorGuard,
3503 file_path: &'static str,
3504 code: &str,
3505 offset: usize,
3506 ) -> Location {
3507 match self {
3508 Self::None => Location {
3509 file_path,
3510 start: offset,
3511 end: offset,
3512 },
3513 Self::AngleBracketed(v) => v.locate(locator, file_path, code, offset),
3514 Self::Parenthesized(v) => v.locate(locator, file_path, code, offset),
3515 }
3516 }
3517}
3518
3519impl Locate for syn::PathSegment {
3520 fn find_loc(
3521 &self,
3522 locator: &mut LocatorGuard,
3523 file_path: &'static str,
3524 code: &str,
3525 offset: usize,
3526 ) -> Location {
3527 (&self.ident, &self.arguments).locate_as_group(locator, file_path, code, offset)
3528 }
3529}
3530
3531impl Locate for syn::PointerMutability {
3532 fn find_loc(
3533 &self,
3534 locator: &mut LocatorGuard,
3535 file_path: &'static str,
3536 code: &str,
3537 offset: usize,
3538 ) -> Location {
3539 match self {
3540 Self::Const(v) => v.locate(locator, file_path, code, offset),
3541 Self::Mut(v) => v.locate(locator, file_path, code, offset),
3542 }
3543 }
3544}
3545
3546impl Locate for syn::PreciseCapture {
3547 fn find_loc(
3548 &self,
3549 locator: &mut LocatorGuard,
3550 file_path: &'static str,
3551 code: &str,
3552 offset: usize,
3553 ) -> Location {
3554 (
3555 &self.use_token,
3556 &self.lt_token,
3557 &self.params,
3558 &self.gt_token,
3559 )
3560 .locate_as_group(locator, file_path, code, offset)
3561 }
3562}
3563
3564impl Locate for syn::PredicateLifetime {
3565 fn find_loc(
3566 &self,
3567 locator: &mut LocatorGuard,
3568 file_path: &'static str,
3569 code: &str,
3570 offset: usize,
3571 ) -> Location {
3572 (&self.lifetime, &self.colon_token, &self.bounds)
3573 .locate_as_group(locator, file_path, code, offset)
3574 }
3575}
3576
3577impl Locate for syn::PredicateType {
3578 fn find_loc(
3579 &self,
3580 locator: &mut LocatorGuard,
3581 file_path: &'static str,
3582 code: &str,
3583 offset: usize,
3584 ) -> Location {
3585 (
3586 &self.lifetimes,
3587 &self.bounded_ty,
3588 &self.colon_token,
3589 &self.bounds,
3590 )
3591 .locate_as_group(locator, file_path, code, offset)
3592 }
3593}
3594
3595impl Locate for syn::QSelf {
3596 fn find_loc(
3597 &self,
3598 locator: &mut LocatorGuard,
3599 file_path: &'static str,
3600 code: &str,
3601 offset: usize,
3602 ) -> Location {
3603 let front_loc = (&self.lt_token, &self.ty, &self.as_token)
3604 .locate_as_group(locator, file_path, code, offset);
3605
3606 const OPEN: char = '<';
3607 const CLOSE: char = '>';
3608
3609 let cur_code = &code[front_loc.end..];
3610
3611 let mut cur = front_loc.end;
3612 let mut level = 1;
3613
3614 for c in cur_code.chars() {
3615 if c == OPEN {
3616 level += 1;
3617 } else if c == CLOSE {
3618 if level == 1 {
3619 break;
3620 }
3621 level -= 1;
3622 }
3623 cur += c.len_utf8();
3624 }
3625
3626 let end = self.gt_token.locate(locator, file_path, code, cur).end;
3627
3628 Location {
3629 file_path,
3630 start: front_loc.start,
3631 end,
3632 }
3633 }
3634}
3635
3636impl Locate for syn::RangeLimits {
3637 fn find_loc(
3638 &self,
3639 locator: &mut LocatorGuard,
3640 file_path: &'static str,
3641 code: &str,
3642 offset: usize,
3643 ) -> Location {
3644 match self {
3645 Self::HalfOpen(v) => v.locate(locator, file_path, code, offset),
3646 Self::Closed(v) => v.locate(locator, file_path, code, offset),
3647 }
3648 }
3649}
3650
3651impl Locate for syn::Receiver {
3652 fn find_loc(
3653 &self,
3654 locator: &mut LocatorGuard,
3655 file_path: &'static str,
3656 code: &str,
3657 offset: usize,
3658 ) -> Location {
3659 if let Some((and_token, reference)) = &self.reference {
3663 if let Some(colon_token) = &self.colon_token {
3664 (
3665 &self.attrs,
3666 and_token,
3667 reference,
3668 &self.mutability,
3669 &self.self_token,
3670 colon_token,
3671 &self.ty,
3672 )
3673 .locate_as_group(locator, file_path, code, offset)
3674 } else {
3675 (
3676 &self.attrs,
3677 and_token,
3678 reference,
3679 &self.mutability,
3680 &self.self_token,
3681 )
3682 .locate_as_group(locator, file_path, code, offset)
3683 }
3684 } else if let Some(colon_token) = &self.colon_token {
3685 (
3686 &self.attrs,
3687 &self.mutability,
3688 &self.self_token,
3689 colon_token,
3690 &self.ty,
3691 )
3692 .locate_as_group(locator, file_path, code, offset)
3693 } else {
3694 (&self.attrs, &self.mutability, &self.self_token)
3695 .locate_as_group(locator, file_path, code, offset)
3696 }
3697 }
3698}
3699
3700impl Locate for syn::ReturnType {
3701 fn find_loc(
3702 &self,
3703 locator: &mut LocatorGuard,
3704 file_path: &'static str,
3705 code: &str,
3706 offset: usize,
3707 ) -> Location {
3708 match self {
3709 Self::Default => Location {
3710 file_path,
3711 start: offset,
3712 end: offset,
3713 },
3714 Self::Type(arrow_token, ty) => {
3715 (arrow_token, ty).locate_as_group(locator, file_path, code, offset)
3716 }
3717 }
3718 }
3719}
3720
3721impl Locate for syn::Signature {
3722 fn find_loc(
3723 &self,
3724 locator: &mut LocatorGuard,
3725 file_path: &'static str,
3726 code: &str,
3727 offset: usize,
3728 ) -> Location {
3729 let loc = Surround {
3730 front: (
3731 &self.constness,
3732 &self.asyncness,
3733 &self.unsafety,
3734 &self.abi,
3735 &self.fn_token,
3736 &self.ident,
3737 &self.generics.lt_token,
3739 &self.generics.params,
3740 &self.generics.gt_token,
3741 ),
3742 surround: &self.paren_token,
3743 inner: (&self.inputs, &self.variadic),
3744 back: (&self.output, &self.generics.where_clause),
3745 }
3746 .locate(locator, file_path, code, offset);
3747
3748 let start = locator.get_location(&self.generics.lt_token).unwrap().start;
3751 let end = locator
3752 .get_location(&self.generics.where_clause)
3753 .unwrap()
3754 .end;
3755 locator.set_location(
3756 &self.generics,
3757 Location {
3758 file_path,
3759 start,
3760 end,
3761 },
3762 );
3763
3764 loc
3765 }
3766}
3767
3768impl Locate for syn::StaticMutability {
3769 fn find_loc(
3770 &self,
3771 locator: &mut LocatorGuard,
3772 file_path: &'static str,
3773 code: &str,
3774 offset: usize,
3775 ) -> Location {
3776 match self {
3777 Self::Mut(v) => v.locate(locator, file_path, code, offset),
3778 Self::None => Location {
3779 file_path,
3780 start: offset,
3781 end: offset,
3782 },
3783 _ => Location {
3784 file_path,
3785 start: offset,
3786 end: offset,
3787 },
3788 }
3789 }
3790}
3791
3792impl Locate for syn::Stmt {
3793 fn find_loc(
3794 &self,
3795 locator: &mut LocatorGuard,
3796 file_path: &'static str,
3797 code: &str,
3798 offset: usize,
3799 ) -> Location {
3800 match self {
3801 Self::Local(v) => v.locate(locator, file_path, code, offset),
3802 Self::Item(v) => v.locate(locator, file_path, code, offset),
3803 Self::Expr(expr, semi_token) => {
3804 (expr, semi_token).locate_as_group(locator, file_path, code, offset)
3805 }
3806 Self::Macro(v) => v.locate(locator, file_path, code, offset),
3807 }
3808 }
3809}
3810
3811impl Locate for syn::StmtMacro {
3812 fn find_loc(
3813 &self,
3814 locator: &mut LocatorGuard,
3815 file_path: &'static str,
3816 code: &str,
3817 offset: usize,
3818 ) -> Location {
3819 (&self.attrs, &self.mac, &self.semi_token).locate_as_group(locator, file_path, code, offset)
3820 }
3821}
3822
3823impl Locate for syn::TraitBound {
3824 fn find_loc(
3825 &self,
3826 locator: &mut LocatorGuard,
3827 file_path: &'static str,
3828 code: &str,
3829 offset: usize,
3830 ) -> Location {
3831 (&self.modifier, &self.lifetimes, &self.path)
3833 .locate_as_group(locator, file_path, code, offset)
3834 }
3835}
3836
3837impl Locate for syn::TraitBoundModifier {
3838 fn find_loc(
3839 &self,
3840 locator: &mut LocatorGuard,
3841 file_path: &'static str,
3842 code: &str,
3843 offset: usize,
3844 ) -> Location {
3845 match self {
3846 Self::None => Location {
3847 file_path,
3848 start: offset,
3849 end: offset,
3850 },
3851 Self::Maybe(v) => v.locate(locator, file_path, code, offset),
3852 }
3853 }
3854}
3855
3856impl Locate for syn::TraitItem {
3857 fn find_loc(
3858 &self,
3859 locator: &mut LocatorGuard,
3860 file_path: &'static str,
3861 code: &str,
3862 offset: usize,
3863 ) -> Location {
3864 match self {
3865 Self::Const(v) => v.locate(locator, file_path, code, offset),
3866 Self::Fn(v) => v.locate(locator, file_path, code, offset),
3867 Self::Type(v) => v.locate(locator, file_path, code, offset),
3868 Self::Macro(v) => v.locate(locator, file_path, code, offset),
3869 Self::Verbatim(_) => Location {
3870 file_path,
3871 start: offset,
3872 end: offset,
3873 },
3874 _ => Location {
3875 file_path,
3876 start: offset,
3877 end: offset,
3878 },
3879 }
3880 }
3881}
3882
3883impl Locate for syn::TraitItemConst {
3884 fn find_loc(
3885 &self,
3886 locator: &mut LocatorGuard,
3887 file_path: &'static str,
3888 code: &str,
3889 offset: usize,
3890 ) -> Location {
3891 if let Some((eq_token, default)) = &self.default {
3892 (
3893 &self.attrs,
3894 &self.const_token,
3895 &self.ident,
3896 &self.generics,
3897 &self.colon_token,
3898 &self.ty,
3899 eq_token,
3900 default,
3901 &self.semi_token,
3902 )
3903 .locate_as_group(locator, file_path, code, offset)
3904 } else {
3905 (
3906 &self.attrs,
3907 &self.const_token,
3908 &self.ident,
3909 &self.generics,
3910 &self.colon_token,
3911 &self.ty,
3912 &self.semi_token,
3913 )
3914 .locate_as_group(locator, file_path, code, offset)
3915 }
3916 }
3917}
3918
3919impl Locate for syn::TraitItemFn {
3920 fn find_loc(
3921 &self,
3922 locator: &mut LocatorGuard,
3923 file_path: &'static str,
3924 code: &str,
3925 offset: usize,
3926 ) -> Location {
3927 (&self.attrs, &self.sig, &self.default, &self.semi_token)
3928 .locate_as_group(locator, file_path, code, offset)
3929 }
3930}
3931
3932impl Locate for syn::TraitItemType {
3933 fn find_loc(
3934 &self,
3935 locator: &mut LocatorGuard,
3936 file_path: &'static str,
3937 code: &str,
3938 offset: usize,
3939 ) -> Location {
3940 if let Some((eq_token, default)) = &self.default {
3941 (
3942 &self.attrs,
3943 &self.type_token,
3944 &self.ident,
3945 &self.generics,
3946 &self.colon_token,
3947 &self.bounds,
3948 eq_token,
3949 default,
3950 &self.semi_token,
3951 )
3952 .locate_as_group(locator, file_path, code, offset)
3953 } else {
3954 (
3955 &self.attrs,
3956 &self.type_token,
3957 &self.ident,
3958 &self.generics,
3959 &self.colon_token,
3960 &self.bounds,
3961 &self.semi_token,
3962 )
3963 .locate_as_group(locator, file_path, code, offset)
3964 }
3965 }
3966}
3967
3968impl Locate for syn::TraitItemMacro {
3969 fn find_loc(
3970 &self,
3971 locator: &mut LocatorGuard,
3972 file_path: &'static str,
3973 code: &str,
3974 offset: usize,
3975 ) -> Location {
3976 (&self.attrs, &self.mac, &self.semi_token).locate_as_group(locator, file_path, code, offset)
3977 }
3978}
3979
3980impl Locate for syn::Type {
3981 fn find_loc(
3982 &self,
3983 locator: &mut LocatorGuard,
3984 file_path: &'static str,
3985 code: &str,
3986 offset: usize,
3987 ) -> Location {
3988 match self {
3989 Self::Array(v) => v.locate(locator, file_path, code, offset),
3990 Self::BareFn(v) => v.locate(locator, file_path, code, offset),
3991 Self::Group(v) => v.locate(locator, file_path, code, offset),
3992 Self::ImplTrait(v) => v.locate(locator, file_path, code, offset),
3993 Self::Infer(v) => v.locate(locator, file_path, code, offset),
3994 Self::Macro(v) => v.locate(locator, file_path, code, offset),
3995 Self::Never(v) => v.locate(locator, file_path, code, offset),
3996 Self::Paren(v) => v.locate(locator, file_path, code, offset),
3997 Self::Path(v) => v.locate(locator, file_path, code, offset),
3998 Self::Ptr(v) => v.locate(locator, file_path, code, offset),
3999 Self::Reference(v) => v.locate(locator, file_path, code, offset),
4000 Self::Slice(v) => v.locate(locator, file_path, code, offset),
4001 Self::TraitObject(v) => v.locate(locator, file_path, code, offset),
4002 Self::Tuple(v) => v.locate(locator, file_path, code, offset),
4003 Self::Verbatim(_) => Location {
4004 file_path,
4005 start: offset,
4006 end: offset,
4007 },
4008 _ => Location {
4009 file_path,
4010 start: offset,
4011 end: offset,
4012 },
4013 }
4014 }
4015}
4016
4017impl Locate for syn::TypeArray {
4018 fn find_loc(
4019 &self,
4020 locator: &mut LocatorGuard,
4021 file_path: &'static str,
4022 code: &str,
4023 offset: usize,
4024 ) -> Location {
4025 Surround {
4026 front: (),
4027 surround: &self.bracket_token,
4028 inner: (&self.elem, &self.semi_token, &self.len),
4029 back: (),
4030 }
4031 .locate(locator, file_path, code, offset)
4032 }
4033}
4034
4035impl Locate for syn::TypeBareFn {
4036 fn find_loc(
4037 &self,
4038 locator: &mut LocatorGuard,
4039 file_path: &'static str,
4040 code: &str,
4041 offset: usize,
4042 ) -> Location {
4043 Surround {
4044 front: (&self.lifetimes, &self.unsafety, &self.abi, &self.fn_token),
4045 surround: &self.paren_token,
4046 inner: (&self.inputs, &self.variadic),
4047 back: &self.output,
4048 }
4049 .locate(locator, file_path, code, offset)
4050 }
4051}
4052
4053impl Locate for syn::TypeGroup {
4054 fn find_loc(
4055 &self,
4056 locator: &mut LocatorGuard,
4057 file_path: &'static str,
4058 code: &str,
4059 offset: usize,
4060 ) -> Location {
4061 (&self.group_token, &self.elem).locate_as_group(locator, file_path, code, offset)
4062 }
4063}
4064
4065impl Locate for syn::TypeImplTrait {
4066 fn find_loc(
4067 &self,
4068 locator: &mut LocatorGuard,
4069 file_path: &'static str,
4070 code: &str,
4071 offset: usize,
4072 ) -> Location {
4073 (&self.impl_token, &self.bounds).locate_as_group(locator, file_path, code, offset)
4074 }
4075}
4076
4077impl Locate for syn::TypeInfer {
4078 fn find_loc(
4079 &self,
4080 locator: &mut LocatorGuard,
4081 file_path: &'static str,
4082 code: &str,
4083 offset: usize,
4084 ) -> Location {
4085 self.underscore_token
4086 .locate(locator, file_path, code, offset)
4087 }
4088}
4089
4090impl Locate for syn::TypeMacro {
4091 fn find_loc(
4092 &self,
4093 locator: &mut LocatorGuard,
4094 file_path: &'static str,
4095 code: &str,
4096 offset: usize,
4097 ) -> Location {
4098 self.mac.locate(locator, file_path, code, offset)
4099 }
4100}
4101
4102impl Locate for syn::TypeNever {
4103 fn find_loc(
4104 &self,
4105 locator: &mut LocatorGuard,
4106 file_path: &'static str,
4107 code: &str,
4108 offset: usize,
4109 ) -> Location {
4110 self.bang_token.locate(locator, file_path, code, offset)
4111 }
4112}
4113
4114impl Locate for syn::TypeParen {
4115 fn find_loc(
4116 &self,
4117 locator: &mut LocatorGuard,
4118 file_path: &'static str,
4119 code: &str,
4120 offset: usize,
4121 ) -> Location {
4122 Surround {
4123 front: (),
4124 surround: &self.paren_token,
4125 inner: &self.elem,
4126 back: (),
4127 }
4128 .locate(locator, file_path, code, offset)
4129 }
4130}
4131
4132impl Locate for syn::TypePath {
4133 fn find_loc(
4134 &self,
4135 locator: &mut LocatorGuard,
4136 file_path: &'static str,
4137 code: &str,
4138 offset: usize,
4139 ) -> Location {
4140 if let Some(qself) = &self.qself {
4141 Qualified {
4142 front: (),
4143 qself,
4144 path: &self.path,
4145 back: (),
4146 }
4147 .locate(locator, file_path, code, offset)
4148 } else {
4149 self.path.locate(locator, file_path, code, offset)
4150 }
4151 }
4152}
4153
4154impl Locate for syn::TypePtr {
4155 fn find_loc(
4156 &self,
4157 locator: &mut LocatorGuard,
4158 file_path: &'static str,
4159 code: &str,
4160 offset: usize,
4161 ) -> Location {
4162 (
4163 &self.star_token,
4164 &self.const_token,
4165 &self.mutability,
4166 &self.elem,
4167 )
4168 .locate_as_group(locator, file_path, code, offset)
4169 }
4170}
4171
4172impl Locate for syn::TypeReference {
4173 fn find_loc(
4174 &self,
4175 locator: &mut LocatorGuard,
4176 file_path: &'static str,
4177 code: &str,
4178 offset: usize,
4179 ) -> Location {
4180 (
4181 &self.and_token,
4182 &self.lifetime,
4183 &self.mutability,
4184 &self.elem,
4185 )
4186 .locate_as_group(locator, file_path, code, offset)
4187 }
4188}
4189
4190impl Locate for syn::TypeSlice {
4191 fn find_loc(
4192 &self,
4193 locator: &mut LocatorGuard,
4194 file_path: &'static str,
4195 code: &str,
4196 offset: usize,
4197 ) -> Location {
4198 Surround {
4199 front: (),
4200 surround: &self.bracket_token,
4201 inner: &self.elem,
4202 back: (),
4203 }
4204 .locate(locator, file_path, code, offset)
4205 }
4206}
4207
4208impl Locate for syn::TypeTraitObject {
4209 fn find_loc(
4210 &self,
4211 locator: &mut LocatorGuard,
4212 file_path: &'static str,
4213 code: &str,
4214 offset: usize,
4215 ) -> Location {
4216 (&self.dyn_token, &self.bounds).locate_as_group(locator, file_path, code, offset)
4217 }
4218}
4219
4220impl Locate for syn::TypeTuple {
4221 fn find_loc(
4222 &self,
4223 locator: &mut LocatorGuard,
4224 file_path: &'static str,
4225 code: &str,
4226 offset: usize,
4227 ) -> Location {
4228 Surround {
4229 front: (),
4230 surround: &self.paren_token,
4231 inner: &self.elems,
4232 back: (),
4233 }
4234 .locate(locator, file_path, code, offset)
4235 }
4236}
4237
4238impl Locate for syn::TypeParam {
4239 fn find_loc(
4240 &self,
4241 locator: &mut LocatorGuard,
4242 file_path: &'static str,
4243 code: &str,
4244 offset: usize,
4245 ) -> Location {
4246 (
4247 &self.attrs,
4248 &self.ident,
4249 &self.colon_token,
4250 &self.bounds,
4251 &self.eq_token,
4252 &self.default,
4253 )
4254 .locate_as_group(locator, file_path, code, offset)
4255 }
4256}
4257
4258impl Locate for syn::TypeParamBound {
4259 fn find_loc(
4260 &self,
4261 locator: &mut LocatorGuard,
4262 file_path: &'static str,
4263 code: &str,
4264 offset: usize,
4265 ) -> Location {
4266 match self {
4267 Self::Trait(v) => v.locate(locator, file_path, code, offset),
4268 Self::Lifetime(v) => v.locate(locator, file_path, code, offset),
4269 Self::PreciseCapture(v) => v.locate(locator, file_path, code, offset),
4270 Self::Verbatim(_) => Location {
4271 file_path,
4272 start: offset,
4273 end: offset,
4274 },
4275 _ => Location {
4276 file_path,
4277 start: offset,
4278 end: offset,
4279 },
4280 }
4281 }
4282}
4283
4284impl Locate for syn::UnOp {
4285 fn find_loc(
4286 &self,
4287 locator: &mut LocatorGuard,
4288 file_path: &'static str,
4289 code: &str,
4290 offset: usize,
4291 ) -> Location {
4292 match self {
4293 Self::Deref(v) => v.locate(locator, file_path, code, offset),
4294 Self::Not(v) => v.locate(locator, file_path, code, offset),
4295 Self::Neg(v) => v.locate(locator, file_path, code, offset),
4296 _ => Location {
4297 file_path,
4298 start: offset,
4299 end: offset,
4300 },
4301 }
4302 }
4303}
4304
4305impl Locate for syn::UseGlob {
4306 fn find_loc(
4307 &self,
4308 locator: &mut LocatorGuard,
4309 file_path: &'static str,
4310 code: &str,
4311 offset: usize,
4312 ) -> Location {
4313 self.star_token.locate(locator, file_path, code, offset)
4314 }
4315}
4316
4317impl Locate for syn::UseGroup {
4318 fn find_loc(
4319 &self,
4320 locator: &mut LocatorGuard,
4321 file_path: &'static str,
4322 code: &str,
4323 offset: usize,
4324 ) -> Location {
4325 Surround {
4326 front: (),
4327 surround: &self.brace_token,
4328 inner: &self.items,
4329 back: (),
4330 }
4331 .locate(locator, file_path, code, offset)
4332 }
4333}
4334
4335impl Locate for syn::UseName {
4336 fn find_loc(
4337 &self,
4338 locator: &mut LocatorGuard,
4339 file_path: &'static str,
4340 code: &str,
4341 offset: usize,
4342 ) -> Location {
4343 self.ident.locate(locator, file_path, code, offset)
4344 }
4345}
4346
4347impl Locate for syn::UsePath {
4348 fn find_loc(
4349 &self,
4350 locator: &mut LocatorGuard,
4351 file_path: &'static str,
4352 code: &str,
4353 offset: usize,
4354 ) -> Location {
4355 (&self.ident, &self.colon2_token, &self.tree)
4356 .locate_as_group(locator, file_path, code, offset)
4357 }
4358}
4359
4360impl Locate for syn::UseRename {
4361 fn find_loc(
4362 &self,
4363 locator: &mut LocatorGuard,
4364 file_path: &'static str,
4365 code: &str,
4366 offset: usize,
4367 ) -> Location {
4368 (&self.ident, &self.as_token, &self.rename)
4369 .locate_as_group(locator, file_path, code, offset)
4370 }
4371}
4372
4373impl Locate for syn::UseTree {
4374 fn find_loc(
4375 &self,
4376 locator: &mut LocatorGuard,
4377 file_path: &'static str,
4378 code: &str,
4379 offset: usize,
4380 ) -> Location {
4381 match self {
4382 Self::Path(v) => v.locate(locator, file_path, code, offset),
4383 Self::Name(v) => v.locate(locator, file_path, code, offset),
4384 Self::Rename(v) => v.locate(locator, file_path, code, offset),
4385 Self::Glob(v) => v.locate(locator, file_path, code, offset),
4386 Self::Group(v) => v.locate(locator, file_path, code, offset),
4387 }
4388 }
4389}
4390
4391impl Locate for syn::Variadic {
4392 fn find_loc(
4393 &self,
4394 locator: &mut LocatorGuard,
4395 file_path: &'static str,
4396 code: &str,
4397 offset: usize,
4398 ) -> Location {
4399 if let Some((pat, colon_token)) = &self.pat {
4400 (&self.attrs, pat, colon_token, &self.dots, &self.comma)
4401 .locate_as_group(locator, file_path, code, offset)
4402 } else {
4403 (&self.attrs, &self.dots, &self.comma).locate_as_group(locator, file_path, code, offset)
4404 }
4405 }
4406}
4407
4408impl Locate for syn::Variant {
4409 fn find_loc(
4410 &self,
4411 locator: &mut LocatorGuard,
4412 file_path: &'static str,
4413 code: &str,
4414 offset: usize,
4415 ) -> Location {
4416 if let Some((eq_token, discriminant)) = &self.discriminant {
4417 (
4418 &self.attrs,
4419 &self.ident,
4420 &self.fields,
4421 eq_token,
4422 discriminant,
4423 )
4424 .locate_as_group(locator, file_path, code, offset)
4425 } else {
4426 (&self.attrs, &self.ident, &self.fields)
4427 .locate_as_group(locator, file_path, code, offset)
4428 }
4429 }
4430}
4431
4432impl Locate for syn::Visibility {
4433 fn find_loc(
4434 &self,
4435 locator: &mut LocatorGuard,
4436 file_path: &'static str,
4437 code: &str,
4438 offset: usize,
4439 ) -> Location {
4440 match self {
4441 Self::Public(v) => v.locate(locator, file_path, code, offset),
4442 Self::Restricted(v) => v.locate(locator, file_path, code, offset),
4443 Self::Inherited => Location {
4444 file_path,
4445 start: offset,
4446 end: offset,
4447 },
4448 }
4449 }
4450}
4451
4452impl Locate for syn::VisRestricted {
4453 fn find_loc(
4454 &self,
4455 locator: &mut LocatorGuard,
4456 file_path: &'static str,
4457 code: &str,
4458 offset: usize,
4459 ) -> Location {
4460 Surround {
4461 front: &self.pub_token,
4462 surround: &self.paren_token,
4463 inner: (&self.in_token, &self.path),
4464 back: (),
4465 }
4466 .locate(locator, file_path, code, offset)
4467 }
4468}
4469
4470impl Locate for syn::WhereClause {
4471 fn find_loc(
4472 &self,
4473 locator: &mut LocatorGuard,
4474 file_path: &'static str,
4475 code: &str,
4476 offset: usize,
4477 ) -> Location {
4478 (&self.where_token, &self.predicates).locate_as_group(locator, file_path, code, offset)
4479 }
4480}
4481
4482impl Locate for syn::WherePredicate {
4483 fn find_loc(
4484 &self,
4485 locator: &mut LocatorGuard,
4486 file_path: &'static str,
4487 code: &str,
4488 offset: usize,
4489 ) -> Location {
4490 match self {
4491 Self::Lifetime(v) => v.locate(locator, file_path, code, offset),
4492 Self::Type(v) => v.locate(locator, file_path, code, offset),
4493 _ => Location {
4494 file_path,
4495 start: offset,
4496 end: offset,
4497 },
4498 }
4499 }
4500}
4501
4502impl<T: Locate> Locate for Option<T> {
4505 fn find_loc(
4506 &self,
4507 locator: &mut LocatorGuard,
4508 file_path: &'static str,
4509 code: &str,
4510 offset: usize,
4511 ) -> Location {
4512 if let Some(inner) = self {
4513 inner.locate(locator, file_path, code, offset)
4514 } else {
4515 Location {
4516 file_path,
4517 start: offset,
4518 end: offset,
4519 }
4520 }
4521 }
4522}
4523
4524impl<T: Locate> Locate for Box<T> {
4525 fn find_loc(
4526 &self,
4527 locator: &mut LocatorGuard,
4528 file_path: &'static str,
4529 code: &str,
4530 offset: usize,
4531 ) -> Location {
4532 let t = &**self;
4533 t.locate(locator, file_path, code, offset)
4534 }
4535}
4536
4537impl<T: Locate> Locate for Vec<T> {
4538 fn find_loc(
4539 &self,
4540 locator: &mut LocatorGuard,
4541 file_path: &'static str,
4542 code: &str,
4543 offset: usize,
4544 ) -> Location {
4545 let mut start = usize::MAX;
4546 let mut end = offset;
4547
4548 for item in self {
4549 let loc = item.locate(locator, file_path, code, end);
4550 start = start.min(loc.start);
4551 end = loc.end;
4552 }
4553
4554 Location {
4555 file_path,
4556 start: if start != usize::MAX { start } else { offset },
4557 end,
4558 }
4559 }
4560}
4561
4562impl<T, S> Locate for syn::punctuated::Punctuated<T, S>
4563where
4564 T: Locate,
4565 S: Locate,
4566{
4567 fn find_loc(
4568 &self,
4569 locator: &mut LocatorGuard,
4570 file_path: &'static str,
4571 code: &str,
4572 offset: usize,
4573 ) -> Location {
4574 let mut start = usize::MAX;
4575 let mut end = offset;
4576
4577 for item in self {
4578 let loc = item.locate(locator, file_path, code, end);
4579 start = start.min(loc.start);
4580 end = loc.end;
4581 }
4582
4583 Location {
4584 file_path,
4585 start: if start != usize::MAX { start } else { offset },
4586 end,
4587 }
4588 }
4589}
4590
4591pub mod helper {
4594 use super::*;
4595
4596 pub fn char_location(
4597 file_path: &'static str,
4598 code: &str,
4599 offset: usize,
4600 content: char,
4601 ) -> Location {
4602 let cur_code = &code[offset..];
4603 let start = offset
4604 + cur_code
4605 .find(content)
4606 .unwrap_or_else(|| panic!("expected `{content}` from `{cur_code}`"));
4607
4608 Location {
4609 file_path,
4610 start,
4611 end: start + content.len_utf8(),
4612 }
4613 }
4614
4615 pub fn str_location(
4616 file_path: &'static str,
4617 code: &str,
4618 offset: usize,
4619 content: &str,
4620 ) -> Location {
4621 let cur_code = &code[offset..];
4622
4623 let start = offset
4624 + cur_code
4625 .find(content)
4626 .unwrap_or_else(|| panic!("expected `{content}` from `{cur_code}`"));
4627
4628 Location {
4629 file_path,
4630 start,
4631 end: start + content.len(),
4632 }
4633 }
4634}