1#![doc = include_str!("../README.md")]
2
3use std::{
4 any::{Any, TypeId},
5 cell::RefCell,
6 collections::HashMap,
7 fmt,
8 pin::Pin,
9};
10
11pub trait LocateEntry: Locate {
12 fn locate_as_entry(self: Pin<&Self>, file_path: &str, code: &str) {
13 let loc = self.location(file_path, code);
14 self.locate(loc.file_path, code, 0);
15 }
16
17 #[doc(hidden)]
18 fn location(self: Pin<&Self>, file_path: &str, code: &str) -> Location {
19 LOCATOR.with_borrow_mut(|locator| locator.insert_file(&*self, file_path, code))
20 }
21}
22
23impl<T: Locate> LocateEntry for T {}
24
25pub trait Locate: Any {
26 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location;
28
29 fn relocate(&self, loc: Location) {
30 LOCATOR.with_borrow_mut(|locator| {
31 locator.set_location(self, loc);
32 });
33 }
34
35 fn locate(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
37 let loc = self.find_loc(file_path, code, offset);
38 LOCATOR.with_borrow_mut(|locator| {
39 locator.set_location(self, loc);
40 });
41 loc
42 }
43
44 fn location(&self) -> Location
45 where
46 Self: fmt::Debug,
47 {
48 LOCATOR
49 .with_borrow(|locator| locator.get_location(self))
50 .unwrap_or_else(|| {
51 panic!(
52 "failed to find the location of `{self:?}`. did you forget `Locate::locate`?"
53 )
54 })
55 }
56
57 fn location_message(&self) -> String
58 where
59 Self: fmt::Debug,
60 {
61 LOCATOR
62 .with_borrow(|locator| {
63 let loc = locator.get_location(self)?;
64 let path = loc.file_path;
65 let code = locator.get_code(path)?;
66 let line = code.as_bytes()[..loc.start]
67 .iter()
68 .filter(|&&b| b == b'\n')
69 .count()
70 + 1;
71 let content = &code[loc.start..loc.end];
72
73 Some(format!("{path}:{line}: {content}"))
74 })
75 .unwrap_or_else(|| {
76 panic!(
77 "failed to find the location of `{self:?}`. did you forget `Locate::locate`?"
78 )
79 })
80 }
81
82 fn code(&self) -> String
83 where
84 Self: fmt::Debug,
85 {
86 LOCATOR
87 .with_borrow(|locator| {
88 let loc = locator.get_location(self)?;
89 let path = loc.file_path;
90 let code = locator.get_code(path)?;
91 let content = &code[loc.start..loc.end];
92
93 Some(content.to_owned())
94 })
95 .unwrap_or_else(|| {
96 panic!(
97 "failed to find the location of `{self:?}`. did you forget `Locate::locate`?"
98 )
99 })
100 }
101}
102
103pub trait LocateGroup {
104 fn locate_as_group(&self, file_path: &'static str, code: &str, offset: usize) -> Location;
105 fn relocate_as_group(&self, loc: Location);
106}
107
108macro_rules! impl_locate_group {
109 ( $($i:expr),* ; $($ri:expr),* ) => {
110 paste::paste! {
111 impl<'a, $([<A $i>]: Locate),*> LocateGroup for ( $( &'a [<A $i>] ),* ) {
112 #[allow(unused_assignments)]
113 fn locate_as_group(&self, file_path: &'static str, code: &str, offset: usize)
114 -> Location
115 {
116 let ( $( [<this $i>] ),* ) = self;
117
118 let mut end = offset;
120 $(
121 let [<loc $i>] = [<this $i>].locate(file_path, code, end);
122 end = [<loc $i>].end;
123 )*
124
125 let mut start = usize::MAX;
127 $(
128 if [<loc $i>].start != [<loc $i>].end {
129 start = start.min( [<loc $i>].start );
130 }
131 )*
132 if start == usize::MAX {
133 start = offset;
134 }
135
136 let mut cur = end;
138 $(
139 if [<loc $ri>].start == [<loc $ri>].end {
140 [<this $ri>].relocate(Location {
141 file_path,
142 start: cur,
143 end: cur
144 });
145 } else {
146 cur = [<loc $ri>].start;
147 }
148 )*
149
150 Location {
151 file_path,
152 start,
153 end
154 }
155 }
156
157 fn relocate_as_group(&self, loc: Location) {
158 let ( $( [<this $i>] ),* ) = self;
159
160 $(
162 [<this $i>].relocate(loc);
163 )*
164 }
165 }
166 }
167 };
168}
169
170impl LocateGroup for () {
171 fn locate_as_group(&self, file_path: &'static str, _code: &str, offset: usize) -> Location {
172 Location {
173 file_path,
174 start: offset,
175 end: offset,
176 }
177 }
178
179 fn relocate_as_group(&self, _: Location) {}
180}
181
182impl<T: Locate> LocateGroup for &T {
183 fn locate_as_group(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
184 self.locate(file_path, code, offset)
185 }
186
187 fn relocate_as_group(&self, loc: Location) {
188 self.relocate(loc)
189 }
190}
191
192impl_locate_group!(0, 1 ; 1, 0);
193impl_locate_group!(0, 1, 2 ; 2, 1, 0);
194impl_locate_group!(0, 1, 2, 3 ; 3, 2, 1, 0);
195impl_locate_group!(0, 1, 2, 3, 4 ; 4, 3, 2, 1, 0);
196impl_locate_group!(0, 1, 2, 3, 4, 5 ; 5, 4, 3, 2, 1, 0);
197impl_locate_group!(0, 1, 2, 3, 4, 5, 6 ; 6, 5, 4, 3, 2, 1, 0);
198impl_locate_group!(0, 1, 2, 3, 4, 5, 6, 7 ; 7, 6, 5, 4, 3, 2, 1, 0);
199impl_locate_group!(0, 1, 2, 3, 4, 5, 6, 7, 8 ; 8, 7, 6, 5, 4, 3, 2, 1, 0);
200impl_locate_group!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ; 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
201impl_locate_group!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ; 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
202
203pub struct Surround<'s, F, S, I, B> {
204 pub front: F,
205 pub surround: &'s S,
206 pub inner: I,
207 pub back: B,
208}
209
210impl<F, S, I, B> Surround<'_, F, S, I, B>
211where
212 F: LocateGroup,
213 S: Locate,
214 I: LocateGroup,
215 B: LocateGroup,
216{
217 pub fn locate(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
218 let front_loc = self.front.locate_as_group(file_path, code, offset);
220 let surround_loc = self.surround.locate(file_path, code, front_loc.end);
221 self.inner
222 .locate_as_group(file_path, code, surround_loc.start + 1);
223 let back_loc = self.back.locate_as_group(file_path, code, surround_loc.end);
224
225 let mut start = front_loc.start;
227 if front_loc.start == front_loc.end {
228 self.front.relocate_as_group(Location {
229 file_path,
230 start: surround_loc.start,
231 end: surround_loc.start,
232 });
233 start = surround_loc.start;
234 }
235
236 let mut end = back_loc.end;
238 if back_loc.start == back_loc.end {
239 self.back.relocate_as_group(Location {
240 file_path,
241 start: surround_loc.end,
242 end: surround_loc.end,
243 });
244 end = surround_loc.end;
245 }
246
247 Location {
248 file_path,
249 start,
250 end,
251 }
252 }
253}
254
255pub struct Qualified<'a, F, B> {
256 pub front: F,
257 pub qself: &'a syn::QSelf,
258 pub path: &'a syn::Path,
259 pub back: B,
260}
261
262impl<F, B> Qualified<'_, F, B>
263where
264 F: LocateGroup,
265 B: LocateGroup,
266{
267 pub fn locate(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
268 let front_loc = self.front.locate_as_group(file_path, code, offset);
270
271 let qself_loc = self.qself.locate(file_path, code, front_loc.end);
272 let qself_mid_loc = self.qself.as_token.location();
273
274 let path_loc = self.path.locate(file_path, code, qself_mid_loc.end);
278
279 let back_loc = self.back.locate_as_group(file_path, code, path_loc.end);
280
281 let mut start = front_loc.start;
283 if front_loc.start == front_loc.end {
284 self.front.relocate_as_group(Location {
285 file_path,
286 start: qself_loc.start,
287 end: qself_loc.start,
288 });
289 start = qself_loc.start;
290 }
291
292 let mut end = back_loc.end;
294 if back_loc.start == back_loc.end {
295 self.back.relocate_as_group(Location {
296 file_path,
297 start: path_loc.end,
298 end: path_loc.end,
299 });
300 end = path_loc.end;
301 }
302
303 Location {
304 file_path,
305 start,
306 end,
307 }
308 }
309}
310
311pub struct Locator {
312 files: HashMap<&'static str, File>,
313 map: HashMap<LocationKey, Location>,
314}
315
316impl Locator {
317 fn new() -> Self {
318 Self {
319 files: HashMap::new(),
320 map: HashMap::new(),
321 }
322 }
323
324 fn insert_file<T: Any + ?Sized>(
326 &mut self,
327 syn_file: &T,
328 file_path: &str,
329 code: &str,
330 ) -> Location {
331 fn inner(this: &mut Locator, key: LocationKey, file_path: &str, code: &str) -> Location {
332 if let Some(loc) = this.map.get(&key) {
333 return *loc;
334 }
335 if this.files.contains_key(file_path) {
336 panic!("duplicate `{file_path}`");
337 }
338
339 let file_path: Box<str> = file_path.into();
340 let file_path = Box::leak(file_path);
341 this.files.insert(file_path, File::new(code));
342
343 let loc = Location {
344 file_path,
345 start: 0,
346 end: code.len(),
347 };
348 this.map.insert(key, loc);
349
350 loc
351 }
352
353 inner(self, LocationKey::new(syn_file), file_path, code)
354 }
355
356 fn set_location<T: Any + ?Sized>(&mut self, syn_node: &T, loc: Location) {
357 self.map.insert(LocationKey::new(syn_node), loc);
358 }
359
360 fn get_location<T: Any + ?Sized>(&self, syn_node: &T) -> Option<Location> {
361 self.map.get(&LocationKey::new(syn_node)).cloned()
362 }
363
364 fn get_code(&self, file_path: &str) -> Option<&str> {
365 self.files.get(file_path).map(|file| file.code.as_str())
366 }
367}
368
369impl Drop for Locator {
370 fn drop(&mut self) {
371 for (file_path, _) in self.files.drain() {
372 let ptr = file_path as *const str as *mut str;
373 unsafe { drop(Box::from_raw(ptr)) };
374 }
375 }
376}
377
378struct File {
379 code: String,
381}
382
383impl File {
384 fn new(code: &str) -> Self {
385 Self {
386 code: Self::remove_non_tokens(code),
387 }
388 }
389
390 fn remove_non_tokens(code: &str) -> String {
393 use regex::{Captures, Regex};
394
395 thread_local! {
398 static RE: Regex = Regex::new(r#"(?x)
399 (//[^\n]*) # Single line comment
400 |
401 (?s)
402 (/\*.*?\*/) # Block comment (Recursion is not supported)
403 "#).unwrap();
404 }
405
406 RE.with(|re| re.replace_all(code, |caps: &Captures| " ".repeat(caps[0].len())))
407 .into_owned()
408 }
409}
410
411#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
412struct LocationKey {
413 ptr: *const (),
414
415 ty: TypeId,
418}
419
420impl LocationKey {
421 fn new<T: Any + ?Sized>(t: &T) -> Self {
422 Self {
423 ptr: t as *const T as *const (),
424 ty: TypeId::of::<T>(),
425 }
426 }
427}
428
429#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
430pub struct Location {
431 pub file_path: &'static str,
432
433 pub start: usize,
435
436 pub end: usize,
438}
439
440thread_local! {
441 static LOCATOR: RefCell<Locator> = RefCell::new(Locator::new());
442}
443
444macro_rules! impl_locate_for_token {
445 ($ty:ty, $token:literal, char) => {
446 impl Locate for $ty {
447 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
448 helper::char_location(file_path, code, offset, $token)
449 }
450 }
451 };
452 ($ty:ty, $token:literal, str) => {
453 impl Locate for $ty {
454 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
455 helper::str_location(file_path, code, offset, $token)
456 }
457 }
458 };
459}
460
461impl_locate_for_token!(syn::Token![abstract], "abstract", str);
462impl_locate_for_token!(syn::Token![as], "as", str);
463impl_locate_for_token!(syn::Token![async], "async", str);
464impl_locate_for_token!(syn::Token![auto], "auto", str);
465impl_locate_for_token!(syn::Token![await], "await", str);
466impl_locate_for_token!(syn::Token![become], "become", str);
467impl_locate_for_token!(syn::Token![box], "box", str);
468impl_locate_for_token!(syn::Token![break], "break", str);
469impl_locate_for_token!(syn::Token![const], "const", str);
470impl_locate_for_token!(syn::Token![continue], "continue", str);
471impl_locate_for_token!(syn::Token![crate], "crate", str);
472impl_locate_for_token!(syn::Token![default], "default", str);
473impl_locate_for_token!(syn::Token![do], "do", str);
474impl_locate_for_token!(syn::Token![dyn], "dyn", str);
475impl_locate_for_token!(syn::Token![else], "else", str);
476impl_locate_for_token!(syn::Token![enum], "enum", str);
477impl_locate_for_token!(syn::Token![extern], "extern", str);
478impl_locate_for_token!(syn::Token![final], "final", str);
479impl_locate_for_token!(syn::Token![fn], "fn", str);
480impl_locate_for_token!(syn::Token![for], "for", str);
481impl_locate_for_token!(syn::Token![if], "if", str);
482impl_locate_for_token!(syn::Token![impl], "impl", str);
483impl_locate_for_token!(syn::Token![in], "in", str);
484impl_locate_for_token!(syn::Token![let], "let", str);
485impl_locate_for_token!(syn::Token![loop], "loop", str);
486impl_locate_for_token!(syn::Token![macro], "macro", str);
487impl_locate_for_token!(syn::Token![match], "match", str);
488impl_locate_for_token!(syn::Token![mod], "mod", str);
489impl_locate_for_token!(syn::Token![move], "move", str);
490impl_locate_for_token!(syn::Token![mut], "mut", str);
491impl_locate_for_token!(syn::Token![override], "override", str);
492impl_locate_for_token!(syn::Token![priv], "priv", str);
493impl_locate_for_token!(syn::Token![pub], "pub", str);
494impl_locate_for_token!(syn::Token![raw], "raw", str);
495impl_locate_for_token!(syn::Token![ref], "ref", str);
496impl_locate_for_token!(syn::Token![return], "return", str);
497impl_locate_for_token!(syn::Token![Self], "Self", str);
498impl_locate_for_token!(syn::Token![self], "self", str);
499impl_locate_for_token!(syn::Token![static], "static", str);
500impl_locate_for_token!(syn::Token![struct], "struct", str);
501impl_locate_for_token!(syn::Token![super], "super", str);
502impl_locate_for_token!(syn::Token![trait], "trait", str);
503impl_locate_for_token!(syn::Token![try], "try", str);
504impl_locate_for_token!(syn::Token![type], "type", str);
505impl_locate_for_token!(syn::Token![typeof], "typeof", str);
506impl_locate_for_token!(syn::Token![union], "union", str);
507impl_locate_for_token!(syn::Token![unsafe], "unsafe", str);
508impl_locate_for_token!(syn::Token![unsized], "unsized", str);
509impl_locate_for_token!(syn::Token![use], "use", str);
510impl_locate_for_token!(syn::Token![virtual], "virtual", str);
511impl_locate_for_token!(syn::Token![where], "where", str);
512impl_locate_for_token!(syn::Token![while], "while", str);
513impl_locate_for_token!(syn::Token![yield], "yield", str);
514impl_locate_for_token!(syn::Token![&], '&', char);
515impl_locate_for_token!(syn::Token![&&], "&&", str);
516impl_locate_for_token!(syn::Token![&=], "&=", str);
517impl_locate_for_token!(syn::Token![@], '@', char);
518impl_locate_for_token!(syn::Token![^], '^', char);
519impl_locate_for_token!(syn::Token![^=], "^=", str);
520impl_locate_for_token!(syn::Token![:], ':', char);
521impl_locate_for_token!(syn::Token![,], ',', char);
522impl_locate_for_token!(syn::Token![$], '$', char);
523impl_locate_for_token!(syn::Token![.], '.', char);
524impl_locate_for_token!(syn::Token![..], "..", str);
525impl_locate_for_token!(syn::Token![...], "...", str);
526impl_locate_for_token!(syn::Token![..=], "..=", str);
527impl_locate_for_token!(syn::Token![=], '=', char);
528impl_locate_for_token!(syn::Token![==], "==", str);
529impl_locate_for_token!(syn::Token![=>], "=>", str);
530impl_locate_for_token!(syn::Token![>=], ">=", str);
531impl_locate_for_token!(syn::Token![>], '>', char);
532impl_locate_for_token!(syn::Token![<-], "<-", str);
533impl_locate_for_token!(syn::Token![<=], "<=", str);
534impl_locate_for_token!(syn::Token![<], '<', char);
535impl_locate_for_token!(syn::Token![-], '-', char);
536impl_locate_for_token!(syn::Token![-=], "-=", str);
537impl_locate_for_token!(syn::Token![!=], "!=", str);
538impl_locate_for_token!(syn::Token![!], '!', char);
539impl_locate_for_token!(syn::Token![|], '|', char);
540impl_locate_for_token!(syn::Token![|=], "|=", str);
541impl_locate_for_token!(syn::Token![||], "||", str);
542impl_locate_for_token!(syn::Token![::], "::", str);
543impl_locate_for_token!(syn::Token![%], '%', char);
544impl_locate_for_token!(syn::Token![%=], "%=", str);
545impl_locate_for_token!(syn::Token![+], '+', char);
546impl_locate_for_token!(syn::Token![+=], "+=", str);
547impl_locate_for_token!(syn::Token![#], '#', char);
548impl_locate_for_token!(syn::Token![?], '?', char);
549impl_locate_for_token!(syn::Token![->], "->", str);
550impl_locate_for_token!(syn::Token![;], ';', char);
551impl_locate_for_token!(syn::Token![<<], "<<", str);
552impl_locate_for_token!(syn::Token![<<=], "<<=", str);
553impl_locate_for_token!(syn::Token![>>], ">>", str);
554impl_locate_for_token!(syn::Token![>>=], ">>=", str);
555impl_locate_for_token!(syn::Token![/], '/', char);
556impl_locate_for_token!(syn::Token![/=], "/=", str);
557impl_locate_for_token!(syn::Token![*], '*', char);
558impl_locate_for_token!(syn::Token![*=], "*=", str);
559impl_locate_for_token!(syn::Token![~], '~', char);
560impl_locate_for_token!(syn::Token![_], '_', char);
561
562impl Locate for syn::token::Group {
563 fn find_loc(&self, file_path: &'static str, _code: &str, offset: usize) -> Location {
564 Location {
565 file_path,
566 start: offset,
567 end: offset,
568 }
569 }
570}
571
572macro_rules! impl_locate_for_pair_tokens {
573 ($ty:ty, $open:literal, $close:literal) => {
574 impl Locate for $ty {
575 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
576 const OPEN: char = $open;
577 const CLOSE: char = $close;
578
579 let code = &code[offset..];
580
581 let mut start = 0;
582 let mut end = 0;
583 let mut cur = offset;
584 let mut level = 0;
585
586 for c in code.chars() {
587 if c == OPEN {
588 if level == 0 {
589 start = cur;
590 }
591 level += 1;
592 } else if c == CLOSE {
593 if level == 1 {
594 end = cur + CLOSE.len_utf8();
595 break;
596 }
597 if level > 0 {
598 level -= 1;
599 }
600 }
601 cur += c.len_utf8();
602 }
603
604 if start >= end {
605 panic!("expected `{OPEN}..{CLOSE}` from {code}");
606 }
607
608 Location {
609 file_path,
610 start,
611 end,
612 }
613 }
614 }
615 };
616}
617
618impl_locate_for_pair_tokens!(syn::token::Brace, '{', '}');
619impl_locate_for_pair_tokens!(syn::token::Bracket, '[', ']');
620impl_locate_for_pair_tokens!(syn::token::Paren, '(', ')');
621
622impl Locate for syn::Abi {
623 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
624 (&self.extern_token, &self.name).locate_as_group(file_path, code, offset)
625 }
626}
627
628impl Locate for syn::AngleBracketedGenericArguments {
629 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
630 (
631 &self.colon2_token,
632 &self.lt_token,
633 &self.args,
634 &self.gt_token,
635 )
636 .locate_as_group(file_path, code, offset)
637 }
638}
639
640impl Locate for syn::Arm {
641 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
642 if let Some((if_token, guard)) = &self.guard {
643 (
644 &self.attrs,
645 &self.pat,
646 if_token,
647 guard,
648 &self.fat_arrow_token,
649 &self.body,
650 &self.comma,
651 )
652 .locate_as_group(file_path, code, offset)
653 } else {
654 (
655 &self.attrs,
656 &self.pat,
657 &self.fat_arrow_token,
658 &self.body,
659 &self.comma,
660 )
661 .locate_as_group(file_path, code, offset)
662 }
663 }
664}
665
666impl Locate for syn::AssocConst {
667 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
668 (&self.ident, &self.generics, &self.eq_token, &self.value)
669 .locate_as_group(file_path, code, offset)
670 }
671}
672
673impl Locate for syn::AssocType {
674 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
675 (&self.ident, &self.generics, &self.eq_token, &self.ty)
676 .locate_as_group(file_path, code, offset)
677 }
678}
679
680impl Locate for syn::Attribute {
681 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
682 let pound_loc = self.pound_token.locate(file_path, code, offset);
683 let bracket_loc = self.bracket_token.locate(file_path, code, pound_loc.end);
684 self.meta.locate(file_path, code, bracket_loc.start + 1);
685
686 Location {
687 file_path,
688 start: pound_loc.start,
689 end: bracket_loc.end,
690 }
691 }
692}
693
694impl Locate for syn::BareFnArg {
695 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
696 if let Some((name, colon_token)) = &self.name {
697 (&self.attrs, name, colon_token, &self.ty).locate_as_group(file_path, code, offset)
698 } else {
699 (&self.attrs, &self.ty).locate_as_group(file_path, code, offset)
700 }
701 }
702}
703
704impl Locate for syn::BareVariadic {
705 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
706 if let Some((name, colon_token)) = &self.name {
707 (&self.attrs, name, colon_token, &self.dots, &self.comma)
708 .locate_as_group(file_path, code, offset)
709 } else {
710 (&self.attrs, &self.dots, &self.comma).locate_as_group(file_path, code, offset)
711 }
712 }
713}
714
715impl Locate for syn::BinOp {
716 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
717 match self {
718 Self::Add(v) => v.locate(file_path, code, offset),
719 Self::Sub(v) => v.locate(file_path, code, offset),
720 Self::Mul(v) => v.locate(file_path, code, offset),
721 Self::Div(v) => v.locate(file_path, code, offset),
722 Self::Rem(v) => v.locate(file_path, code, offset),
723 Self::And(v) => v.locate(file_path, code, offset),
724 Self::Or(v) => v.locate(file_path, code, offset),
725 Self::BitXor(v) => v.locate(file_path, code, offset),
726 Self::BitAnd(v) => v.locate(file_path, code, offset),
727 Self::BitOr(v) => v.locate(file_path, code, offset),
728 Self::Shl(v) => v.locate(file_path, code, offset),
729 Self::Shr(v) => v.locate(file_path, code, offset),
730 Self::Eq(v) => v.locate(file_path, code, offset),
731 Self::Lt(v) => v.locate(file_path, code, offset),
732 Self::Le(v) => v.locate(file_path, code, offset),
733 Self::Ne(v) => v.locate(file_path, code, offset),
734 Self::Ge(v) => v.locate(file_path, code, offset),
735 Self::Gt(v) => v.locate(file_path, code, offset),
736 Self::AddAssign(v) => v.locate(file_path, code, offset),
737 Self::SubAssign(v) => v.locate(file_path, code, offset),
738 Self::MulAssign(v) => v.locate(file_path, code, offset),
739 Self::DivAssign(v) => v.locate(file_path, code, offset),
740 Self::RemAssign(v) => v.locate(file_path, code, offset),
741 Self::BitXorAssign(v) => v.locate(file_path, code, offset),
742 Self::BitAndAssign(v) => v.locate(file_path, code, offset),
743 Self::BitOrAssign(v) => v.locate(file_path, code, offset),
744 Self::ShlAssign(v) => v.locate(file_path, code, offset),
745 Self::ShrAssign(v) => v.locate(file_path, code, offset),
746 _ => Location {
747 file_path,
748 start: offset,
749 end: offset,
750 },
751 }
752 }
753}
754
755impl Locate for syn::Block {
756 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
757 Surround {
758 front: (),
759 surround: &self.brace_token,
760 inner: &self.stmts,
761 back: (),
762 }
763 .locate(file_path, code, offset)
764 }
765}
766
767impl Locate for syn::BoundLifetimes {
768 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
769 (
770 &self.for_token,
771 &self.lt_token,
772 &self.lifetimes,
773 &self.gt_token,
774 )
775 .locate_as_group(file_path, code, offset)
776 }
777}
778
779impl Locate for syn::CapturedParam {
780 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
781 match self {
782 Self::Lifetime(v) => v.locate(file_path, code, offset),
783 Self::Ident(v) => v.locate(file_path, code, offset),
784 _ => Location {
785 file_path,
786 start: offset,
787 end: offset,
788 },
789 }
790 }
791}
792
793impl Locate for syn::ConstParam {
794 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
795 (
796 &self.attrs,
797 &self.const_token,
798 &self.ident,
799 &self.colon_token,
800 &self.ty,
801 &self.eq_token,
802 &self.default,
803 )
804 .locate_as_group(file_path, code, offset)
805 }
806}
807
808impl Locate for syn::Constraint {
809 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
810 (&self.ident, &self.generics, &self.colon_token, &self.bounds)
811 .locate_as_group(file_path, code, offset)
812 }
813}
814
815impl Locate for syn::Expr {
816 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
817 match self {
818 Self::Array(v) => v.locate(file_path, code, offset),
819 Self::Assign(v) => v.locate(file_path, code, offset),
820 Self::Async(v) => v.locate(file_path, code, offset),
821 Self::Await(v) => v.locate(file_path, code, offset),
822 Self::Binary(v) => v.locate(file_path, code, offset),
823 Self::Block(v) => v.locate(file_path, code, offset),
824 Self::Break(v) => v.locate(file_path, code, offset),
825 Self::Call(v) => v.locate(file_path, code, offset),
826 Self::Cast(v) => v.locate(file_path, code, offset),
827 Self::Closure(v) => v.locate(file_path, code, offset),
828 Self::Const(v) => v.locate(file_path, code, offset),
829 Self::Continue(v) => v.locate(file_path, code, offset),
830 Self::Field(v) => v.locate(file_path, code, offset),
831 Self::ForLoop(v) => v.locate(file_path, code, offset),
832 Self::Group(v) => v.locate(file_path, code, offset),
833 Self::If(v) => v.locate(file_path, code, offset),
834 Self::Index(v) => v.locate(file_path, code, offset),
835 Self::Infer(v) => v.locate(file_path, code, offset),
836 Self::Let(v) => v.locate(file_path, code, offset),
837 Self::Lit(v) => v.locate(file_path, code, offset),
838 Self::Loop(v) => v.locate(file_path, code, offset),
839 Self::Macro(v) => v.locate(file_path, code, offset),
840 Self::Match(v) => v.locate(file_path, code, offset),
841 Self::MethodCall(v) => v.locate(file_path, code, offset),
842 Self::Paren(v) => v.locate(file_path, code, offset),
843 Self::Path(v) => v.locate(file_path, code, offset),
844 Self::Range(v) => v.locate(file_path, code, offset),
845 Self::RawAddr(v) => v.locate(file_path, code, offset),
846 Self::Reference(v) => v.locate(file_path, code, offset),
847 Self::Repeat(v) => v.locate(file_path, code, offset),
848 Self::Return(v) => v.locate(file_path, code, offset),
849 Self::Struct(v) => v.locate(file_path, code, offset),
850 Self::Try(v) => v.locate(file_path, code, offset),
851 Self::TryBlock(v) => v.locate(file_path, code, offset),
852 Self::Tuple(v) => v.locate(file_path, code, offset),
853 Self::Unary(v) => v.locate(file_path, code, offset),
854 Self::Unsafe(v) => v.locate(file_path, code, offset),
855 Self::Verbatim(_) => Location {
856 file_path,
857 start: offset,
858 end: offset,
859 },
860 Self::While(v) => v.locate(file_path, code, offset),
861 Self::Yield(v) => v.locate(file_path, code, offset),
862 _ => Location {
863 file_path,
864 start: offset,
865 end: offset,
866 },
867 }
868 }
869}
870
871impl Locate for syn::ExprArray {
872 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
873 Surround {
874 front: &self.attrs,
875 surround: &self.bracket_token,
876 inner: &self.elems,
877 back: (),
878 }
879 .locate(file_path, code, offset)
880 }
881}
882
883impl Locate for syn::ExprAssign {
884 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
885 (&self.attrs, &self.left, &self.eq_token, &self.right)
886 .locate_as_group(file_path, code, offset)
887 }
888}
889
890impl Locate for syn::ExprAsync {
891 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
892 (&self.attrs, &self.async_token, &self.capture, &self.block)
893 .locate_as_group(file_path, code, offset)
894 }
895}
896
897impl Locate for syn::ExprAwait {
898 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
899 (&self.attrs, &self.base, &self.dot_token, &self.await_token)
900 .locate_as_group(file_path, code, offset)
901 }
902}
903
904impl Locate for syn::ExprBinary {
905 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
906 (&self.attrs, &self.left, &self.op, &self.right).locate_as_group(file_path, code, offset)
907 }
908}
909
910impl Locate for syn::ExprBlock {
911 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
912 (&self.attrs, &self.label, &self.block).locate_as_group(file_path, code, offset)
913 }
914}
915
916impl Locate for syn::ExprBreak {
917 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
918 (&self.attrs, &self.break_token, &self.label, &self.expr)
919 .locate_as_group(file_path, code, offset)
920 }
921}
922
923impl Locate for syn::ExprCall {
924 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
925 Surround {
926 front: (&self.attrs, &self.func),
927 surround: &self.paren_token,
928 inner: &self.args,
929 back: (),
930 }
931 .locate(file_path, code, offset)
932 }
933}
934
935impl Locate for syn::ExprCast {
936 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
937 (&self.attrs, &self.expr, &self.as_token, &self.ty).locate_as_group(file_path, code, offset)
938 }
939}
940
941impl Locate for syn::ExprClosure {
942 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
943 (
944 &self.attrs,
945 &self.lifetimes,
946 &self.constness,
947 &self.movability,
948 &self.asyncness,
949 &self.capture,
950 &self.or1_token,
951 &self.inputs,
952 &self.or2_token,
953 &self.output,
954 &self.body,
955 )
956 .locate_as_group(file_path, code, offset)
957 }
958}
959
960impl Locate for syn::ExprConst {
961 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
962 (&self.attrs, &self.const_token, &self.block).locate_as_group(file_path, code, offset)
963 }
964}
965
966impl Locate for syn::ExprContinue {
967 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
968 (&self.attrs, &self.continue_token, &self.label).locate_as_group(file_path, code, offset)
969 }
970}
971
972impl Locate for syn::ExprField {
973 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
974 (&self.attrs, &self.base, &self.dot_token, &self.member)
975 .locate_as_group(file_path, code, offset)
976 }
977}
978
979impl Locate for syn::ExprForLoop {
980 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
981 (
982 &self.attrs,
983 &self.label,
984 &self.for_token,
985 &self.pat,
986 &self.in_token,
987 &self.expr,
988 &self.body,
989 )
990 .locate_as_group(file_path, code, offset)
991 }
992}
993
994impl Locate for syn::ExprGroup {
995 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
996 (&self.attrs, &self.group_token, &self.expr).locate_as_group(file_path, code, offset)
997 }
998}
999
1000impl Locate for syn::ExprIf {
1001 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1002 if let Some((else_token, else_branch)) = &self.else_branch {
1003 (
1004 &self.attrs,
1005 &self.if_token,
1006 &self.cond,
1007 &self.then_branch,
1008 else_token,
1009 else_branch,
1010 )
1011 .locate_as_group(file_path, code, offset)
1012 } else {
1013 (&self.attrs, &self.if_token, &self.cond, &self.then_branch)
1014 .locate_as_group(file_path, code, offset)
1015 }
1016 }
1017}
1018
1019impl Locate for syn::ExprIndex {
1020 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1021 Surround {
1022 front: (&self.attrs, &self.expr),
1023 surround: &self.bracket_token,
1024 inner: &self.index,
1025 back: (),
1026 }
1027 .locate(file_path, code, offset)
1028 }
1029}
1030
1031impl Locate for syn::ExprInfer {
1032 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1033 (&self.attrs, &self.underscore_token).locate_as_group(file_path, code, offset)
1034 }
1035}
1036
1037impl Locate for syn::ExprLet {
1038 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1039 (
1040 &self.attrs,
1041 &self.let_token,
1042 &self.pat,
1043 &self.eq_token,
1044 &self.expr,
1045 )
1046 .locate_as_group(file_path, code, offset)
1047 }
1048}
1049
1050impl Locate for syn::ExprLit {
1051 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1052 (&self.attrs, &self.lit).locate_as_group(file_path, code, offset)
1053 }
1054}
1055
1056impl Locate for syn::ExprLoop {
1057 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1058 (&self.attrs, &self.label, &self.loop_token, &self.body)
1059 .locate_as_group(file_path, code, offset)
1060 }
1061}
1062
1063impl Locate for syn::ExprMacro {
1064 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1065 (&self.attrs, &self.mac).locate_as_group(file_path, code, offset)
1066 }
1067}
1068
1069impl Locate for syn::ExprMatch {
1070 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1071 Surround {
1072 front: (&self.attrs, &self.match_token, &self.expr),
1073 surround: &self.brace_token,
1074 inner: &self.arms,
1075 back: (),
1076 }
1077 .locate(file_path, code, offset)
1078 }
1079}
1080
1081impl Locate for syn::ExprMethodCall {
1082 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1083 Surround {
1084 front: (
1085 &self.attrs,
1086 &self.receiver,
1087 &self.dot_token,
1088 &self.method,
1089 &self.turbofish,
1090 ),
1091 surround: &self.paren_token,
1092 inner: &self.args,
1093 back: (),
1094 }
1095 .locate(file_path, code, offset)
1096 }
1097}
1098
1099impl Locate for syn::ExprParen {
1100 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1101 Surround {
1102 front: &self.attrs,
1103 surround: &self.paren_token,
1104 inner: &self.expr,
1105 back: (),
1106 }
1107 .locate(file_path, code, offset)
1108 }
1109}
1110
1111impl Locate for syn::ExprPath {
1112 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1113 if let Some(qself) = &self.qself {
1114 Qualified {
1115 front: &self.attrs,
1116 qself,
1117 path: &self.path,
1118 back: (),
1119 }
1120 .locate(file_path, code, offset)
1121 } else {
1122 (&self.attrs, &self.path).locate_as_group(file_path, code, offset)
1123 }
1124 }
1125}
1126
1127impl Locate for syn::ExprRange {
1128 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1129 match (&self.start, &self.end) {
1130 (Some(start), Some(end)) => {
1131 (&self.attrs, start, &self.limits, end).locate_as_group(file_path, code, offset)
1132 }
1133 (Some(start), None) => {
1134 (&self.attrs, start, &self.limits).locate_as_group(file_path, code, offset)
1135 }
1136 (None, Some(end)) => {
1137 (&self.attrs, &self.limits, end).locate_as_group(file_path, code, offset)
1138 }
1139 (None, None) => (&self.attrs, &self.limits).locate_as_group(file_path, code, offset),
1140 }
1141 }
1142}
1143
1144impl Locate for syn::ExprRawAddr {
1145 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1146 (
1147 &self.attrs,
1148 &self.and_token,
1149 &self.raw,
1150 &self.mutability,
1151 &self.expr,
1152 )
1153 .locate_as_group(file_path, code, offset)
1154 }
1155}
1156
1157impl Locate for syn::ExprReference {
1158 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1159 (&self.attrs, &self.and_token, &self.mutability, &self.expr)
1160 .locate_as_group(file_path, code, offset)
1161 }
1162}
1163
1164impl Locate for syn::ExprRepeat {
1165 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1166 Surround {
1167 front: &self.attrs,
1168 surround: &self.bracket_token,
1169 inner: (&self.expr, &self.semi_token, &self.len),
1170 back: (),
1171 }
1172 .locate(file_path, code, offset)
1173 }
1174}
1175
1176impl Locate for syn::ExprReturn {
1177 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1178 (&self.attrs, &self.return_token, &self.expr).locate_as_group(file_path, code, offset)
1179 }
1180}
1181
1182impl Locate for syn::ExprStruct {
1183 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1184 let front_loc = if let Some(qself) = &self.qself {
1185 Qualified {
1186 front: &self.attrs,
1187 qself,
1188 path: &self.path,
1189 back: (),
1190 }
1191 .locate(file_path, code, offset)
1192 } else {
1193 (&self.attrs, &self.path).locate_as_group(file_path, code, offset)
1194 };
1195
1196 let back_loc = Surround {
1197 front: (),
1198 surround: &self.brace_token,
1199 inner: (&self.fields, &self.dot2_token, &self.rest),
1200 back: (),
1201 }
1202 .locate(file_path, code, front_loc.end);
1203
1204 Location {
1205 file_path,
1206 start: front_loc.start,
1207 end: back_loc.end,
1208 }
1209 }
1210}
1211
1212impl Locate for syn::ExprTry {
1213 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1214 (&self.attrs, &self.expr, &self.question_token).locate_as_group(file_path, code, offset)
1215 }
1216}
1217
1218impl Locate for syn::ExprTryBlock {
1219 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1220 (&self.attrs, &self.try_token, &self.block).locate_as_group(file_path, code, offset)
1221 }
1222}
1223
1224impl Locate for syn::ExprTuple {
1225 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1226 Surround {
1227 front: &self.attrs,
1228 surround: &self.paren_token,
1229 inner: &self.elems,
1230 back: (),
1231 }
1232 .locate(file_path, code, offset)
1233 }
1234}
1235
1236impl Locate for syn::ExprUnary {
1237 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1238 (&self.attrs, &self.op, &self.expr).locate_as_group(file_path, code, offset)
1239 }
1240}
1241
1242impl Locate for syn::ExprUnsafe {
1243 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1244 (&self.attrs, &self.unsafe_token, &self.block).locate_as_group(file_path, code, offset)
1245 }
1246}
1247
1248impl Locate for syn::ExprWhile {
1249 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1250 (
1251 &self.attrs,
1252 &self.label,
1253 &self.while_token,
1254 &self.cond,
1255 &self.body,
1256 )
1257 .locate_as_group(file_path, code, offset)
1258 }
1259}
1260
1261impl Locate for syn::ExprYield {
1262 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1263 (&self.attrs, &self.yield_token, &self.expr).locate_as_group(file_path, code, offset)
1264 }
1265}
1266
1267impl Locate for syn::Field {
1268 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1269 (
1270 &self.attrs,
1271 &self.vis,
1272 &self.mutability,
1273 &self.ident,
1274 &self.colon_token,
1275 &self.ty,
1276 )
1277 .locate_as_group(file_path, code, offset)
1278 }
1279}
1280
1281impl Locate for syn::FieldMutability {
1282 fn find_loc(&self, file_path: &'static str, _code: &str, offset: usize) -> Location {
1283 Location {
1284 file_path,
1285 start: offset,
1286 end: offset,
1287 }
1288 }
1289}
1290
1291impl Locate for syn::FieldPat {
1292 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1293 (&self.attrs, &self.member, &self.colon_token, &self.pat)
1294 .locate_as_group(file_path, code, offset)
1295 }
1296}
1297
1298impl Locate for syn::Fields {
1299 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1300 match self {
1301 Self::Named(v) => v.locate(file_path, code, offset),
1302 Self::Unnamed(v) => v.locate(file_path, code, offset),
1303 Self::Unit => Location {
1304 file_path,
1305 start: offset,
1306 end: offset,
1307 },
1308 }
1309 }
1310}
1311
1312impl Locate for syn::FieldsNamed {
1313 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1314 Surround {
1315 front: (),
1316 surround: &self.brace_token,
1317 inner: &self.named,
1318 back: (),
1319 }
1320 .locate(file_path, code, offset)
1321 }
1322}
1323
1324impl Locate for syn::FieldsUnnamed {
1325 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1326 Surround {
1327 front: (),
1328 surround: &self.paren_token,
1329 inner: &self.unnamed,
1330 back: (),
1331 }
1332 .locate(file_path, code, offset)
1333 }
1334}
1335
1336impl Locate for syn::FieldValue {
1337 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1338 (&self.attrs, &self.member, &self.colon_token, &self.expr)
1339 .locate_as_group(file_path, code, offset)
1340 }
1341}
1342
1343impl Locate for syn::File {
1344 fn find_loc(&self, file_path: &'static str, code: &str, _offset: usize) -> Location {
1345 (&self.attrs, &self.items).locate_as_group(file_path, code, 0)
1346 }
1347}
1348
1349impl Locate for syn::FnArg {
1350 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1351 match self {
1352 Self::Receiver(v) => v.locate(file_path, code, offset),
1353 Self::Typed(v) => v.locate(file_path, code, offset),
1354 }
1355 }
1356}
1357
1358impl Locate for syn::ForeignItem {
1359 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1360 match self {
1361 Self::Fn(v) => v.locate(file_path, code, offset),
1362 Self::Static(v) => v.locate(file_path, code, offset),
1363 Self::Type(v) => v.locate(file_path, code, offset),
1364 Self::Macro(v) => v.locate(file_path, code, offset),
1365 Self::Verbatim(_) => Location {
1366 file_path,
1367 start: offset,
1368 end: offset,
1369 },
1370 _ => Location {
1371 file_path,
1372 start: offset,
1373 end: offset,
1374 },
1375 }
1376 }
1377}
1378
1379impl Locate for syn::ForeignItemFn {
1380 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1381 (&self.attrs, &self.vis, &self.sig, &self.semi_token)
1382 .locate_as_group(file_path, code, offset)
1383 }
1384}
1385
1386impl Locate for syn::ForeignItemStatic {
1387 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1388 (
1389 &self.attrs,
1390 &self.vis,
1391 &self.static_token,
1392 &self.mutability,
1393 &self.ident,
1394 &self.colon_token,
1395 &self.ty,
1396 &self.semi_token,
1397 )
1398 .locate_as_group(file_path, code, offset)
1399 }
1400}
1401
1402impl Locate for syn::ForeignItemType {
1403 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1404 (
1405 &self.attrs,
1406 &self.vis,
1407 &self.type_token,
1408 &self.ident,
1409 &self.generics,
1410 &self.semi_token,
1411 )
1412 .locate_as_group(file_path, code, offset)
1413 }
1414}
1415
1416impl Locate for syn::ForeignItemMacro {
1417 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1418 (&self.attrs, &self.mac, &self.semi_token).locate_as_group(file_path, code, offset)
1419 }
1420}
1421
1422impl Locate for syn::GenericArgument {
1423 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1424 match self {
1425 Self::Lifetime(v) => v.locate(file_path, code, offset),
1426 Self::Type(v) => v.locate(file_path, code, offset),
1427 Self::Const(v) => v.locate(file_path, code, offset),
1428 Self::AssocType(v) => v.locate(file_path, code, offset),
1429 Self::AssocConst(v) => v.locate(file_path, code, offset),
1430 Self::Constraint(v) => v.locate(file_path, code, offset),
1431 _ => Location {
1432 file_path,
1433 start: offset,
1434 end: offset,
1435 },
1436 }
1437 }
1438}
1439
1440impl Locate for syn::GenericParam {
1441 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1442 match self {
1443 Self::Lifetime(v) => v.locate(file_path, code, offset),
1444 Self::Type(v) => v.locate(file_path, code, offset),
1445 Self::Const(v) => v.locate(file_path, code, offset),
1446 }
1447 }
1448}
1449
1450impl Locate for syn::Generics {
1451 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1452 (
1453 &self.lt_token,
1454 &self.params,
1455 &self.gt_token,
1456 &self.where_clause,
1457 )
1458 .locate_as_group(file_path, code, offset)
1459 }
1460}
1461
1462impl Locate for syn::Ident {
1463 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1464 let code = &code[offset..];
1465
1466 let ident = self.to_string();
1467 let start = offset
1468 + code
1469 .find(&ident)
1470 .unwrap_or_else(|| panic!("expected `{ident}` from `{code}`"));
1471
1472 Location {
1473 file_path,
1474 start,
1475 end: start + ident.len(),
1476 }
1477 }
1478}
1479
1480impl Locate for syn::ImplItem {
1481 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1482 match self {
1483 Self::Const(v) => v.locate(file_path, code, offset),
1484 Self::Fn(v) => v.locate(file_path, code, offset),
1485 Self::Type(v) => v.locate(file_path, code, offset),
1486 Self::Macro(v) => v.locate(file_path, code, offset),
1487 Self::Verbatim(_) => Location {
1488 file_path,
1489 start: offset,
1490 end: offset,
1491 },
1492 _ => Location {
1493 file_path,
1494 start: offset,
1495 end: offset,
1496 },
1497 }
1498 }
1499}
1500
1501impl Locate for syn::ImplItemConst {
1502 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1503 (
1504 &self.attrs,
1505 &self.vis,
1506 &self.defaultness,
1507 &self.const_token,
1508 &self.ident,
1509 &self.generics,
1510 &self.colon_token,
1511 &self.ty,
1512 &self.eq_token,
1513 &self.expr,
1514 &self.semi_token,
1515 )
1516 .locate_as_group(file_path, code, offset)
1517 }
1518}
1519
1520impl Locate for syn::ImplItemFn {
1521 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1522 (
1523 &self.attrs,
1524 &self.vis,
1525 &self.defaultness,
1526 &self.sig,
1527 &self.block,
1528 )
1529 .locate_as_group(file_path, code, offset)
1530 }
1531}
1532
1533impl Locate for syn::ImplItemType {
1534 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1535 (
1536 &self.attrs,
1537 &self.vis,
1538 &self.defaultness,
1539 &self.type_token,
1540 &self.ident,
1541 &self.generics,
1542 &self.eq_token,
1543 &self.ty,
1544 &self.semi_token,
1545 )
1546 .locate_as_group(file_path, code, offset)
1547 }
1548}
1549
1550impl Locate for syn::ImplItemMacro {
1551 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1552 (&self.attrs, &self.mac, &self.semi_token).locate_as_group(file_path, code, offset)
1553 }
1554}
1555
1556impl Locate for syn::ImplRestriction {
1557 fn find_loc(&self, file_path: &'static str, _code: &str, offset: usize) -> Location {
1558 Location {
1559 file_path,
1560 start: offset,
1561 end: offset,
1562 }
1563 }
1564}
1565
1566impl Locate for syn::Index {
1567 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1568 let value = self.index.to_string();
1569 helper::str_location(file_path, code, offset, &value)
1570 }
1571}
1572
1573impl Locate for syn::Item {
1574 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1575 match self {
1576 Self::Const(v) => v.locate(file_path, code, offset),
1577 Self::Enum(v) => v.locate(file_path, code, offset),
1578 Self::ExternCrate(v) => v.locate(file_path, code, offset),
1579 Self::Fn(v) => v.locate(file_path, code, offset),
1580 Self::ForeignMod(v) => v.locate(file_path, code, offset),
1581 Self::Impl(v) => v.locate(file_path, code, offset),
1582 Self::Macro(v) => v.locate(file_path, code, offset),
1583 Self::Mod(v) => v.locate(file_path, code, offset),
1584 Self::Static(v) => v.locate(file_path, code, offset),
1585 Self::Struct(v) => v.locate(file_path, code, offset),
1586 Self::Trait(v) => v.locate(file_path, code, offset),
1587 Self::TraitAlias(v) => v.locate(file_path, code, offset),
1588 Self::Type(v) => v.locate(file_path, code, offset),
1589 Self::Union(v) => v.locate(file_path, code, offset),
1590 Self::Use(v) => v.locate(file_path, code, offset),
1591 Self::Verbatim(_) => Location {
1592 file_path,
1593 start: offset,
1594 end: offset,
1595 },
1596 _ => Location {
1597 file_path,
1598 start: offset,
1599 end: offset,
1600 },
1601 }
1602 }
1603}
1604
1605impl Locate for syn::ItemConst {
1606 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1607 (
1608 &self.attrs,
1609 &self.vis,
1610 &self.const_token,
1611 &self.ident,
1612 &self.generics,
1613 &self.colon_token,
1614 &self.ty,
1615 &self.eq_token,
1616 &self.expr,
1617 &self.semi_token,
1618 )
1619 .locate_as_group(file_path, code, offset)
1620 }
1621}
1622
1623impl Locate for syn::ItemEnum {
1624 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1625 Surround {
1626 front: (
1627 &self.attrs,
1628 &self.vis,
1629 &self.enum_token,
1630 &self.ident,
1631 &self.generics,
1632 ),
1633 surround: &self.brace_token,
1634 inner: &self.variants,
1635 back: (),
1636 }
1637 .locate(file_path, code, offset)
1638 }
1639}
1640
1641impl Locate for syn::ItemExternCrate {
1642 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1643 if let Some((as_token, rename)) = &self.rename {
1644 (
1645 &self.attrs,
1646 &self.vis,
1647 &self.extern_token,
1648 &self.crate_token,
1649 &self.ident,
1650 as_token,
1651 rename,
1652 &self.semi_token,
1653 )
1654 .locate_as_group(file_path, code, offset)
1655 } else {
1656 (
1657 &self.attrs,
1658 &self.vis,
1659 &self.extern_token,
1660 &self.crate_token,
1661 &self.ident,
1662 &self.semi_token,
1663 )
1664 .locate_as_group(file_path, code, offset)
1665 }
1666 }
1667}
1668
1669impl Locate for syn::ItemFn {
1670 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1671 (&self.attrs, &self.vis, &self.sig, &self.block).locate_as_group(file_path, code, offset)
1672 }
1673}
1674
1675impl Locate for syn::ItemForeignMod {
1676 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1677 Surround {
1678 front: (&self.attrs, &self.unsafety, &self.abi),
1679 surround: &self.brace_token,
1680 inner: &self.items,
1681 back: (),
1682 }
1683 .locate(file_path, code, offset)
1684 }
1685}
1686
1687impl Locate for syn::ItemImpl {
1688 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1689 if let Some((exc_token, path, for_token)) = &self.trait_ {
1690 Surround {
1691 front: (
1692 &self.attrs,
1693 &self.defaultness,
1694 &self.unsafety,
1695 &self.impl_token,
1696 &self.generics,
1697 exc_token,
1698 path,
1699 for_token,
1700 &self.self_ty,
1701 ),
1702 surround: &self.brace_token,
1703 inner: &self.items,
1704 back: (),
1705 }
1706 .locate(file_path, code, offset)
1707 } else {
1708 Surround {
1709 front: (
1710 &self.attrs,
1711 &self.defaultness,
1712 &self.unsafety,
1713 &self.impl_token,
1714 &self.generics,
1715 &self.self_ty,
1716 ),
1717 surround: &self.brace_token,
1718 inner: &self.items,
1719 back: (),
1720 }
1721 .locate(file_path, code, offset)
1722 }
1723 }
1724}
1725
1726impl Locate for syn::ItemMacro {
1727 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1728 (&self.attrs, &self.ident, &self.mac, &self.semi_token)
1729 .locate_as_group(file_path, code, offset)
1730 }
1731}
1732
1733impl Locate for syn::ItemMod {
1734 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1735 match (&self.content, &self.semi) {
1736 (Some((brace, items)), Some(semi_token)) => Surround {
1737 front: (&self.attrs, &self.vis, &self.mod_token, &self.ident),
1738 surround: brace,
1739 inner: items,
1740 back: semi_token,
1741 }
1742 .locate(file_path, code, offset),
1743 (Some((brace, items)), None) => Surround {
1744 front: (&self.attrs, &self.vis, &self.mod_token, &self.ident),
1745 surround: brace,
1746 inner: items,
1747 back: (),
1748 }
1749 .locate(file_path, code, offset),
1750 (None, Some(semi_token)) => (
1751 &self.attrs,
1752 &self.vis,
1753 &self.mod_token,
1754 &self.ident,
1755 semi_token,
1756 )
1757 .locate_as_group(file_path, code, offset),
1758 (None, None) => (&self.attrs, &self.vis, &self.mod_token, &self.ident)
1759 .locate_as_group(file_path, code, offset),
1760 }
1761 }
1762}
1763
1764impl Locate for syn::ItemStatic {
1765 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1766 (
1767 &self.attrs,
1768 &self.vis,
1769 &self.static_token,
1770 &self.mutability,
1771 &self.ident,
1772 &self.colon_token,
1773 &self.ty,
1774 &self.eq_token,
1775 &self.expr,
1776 &self.semi_token,
1777 )
1778 .locate_as_group(file_path, code, offset)
1779 }
1780}
1781
1782impl Locate for syn::ItemStruct {
1783 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1784 (
1785 &self.attrs,
1786 &self.vis,
1787 &self.struct_token,
1788 &self.ident,
1789 &self.generics,
1790 &self.fields,
1791 &self.semi_token,
1792 )
1793 .locate_as_group(file_path, code, offset)
1794 }
1795}
1796
1797impl Locate for syn::ItemTrait {
1798 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1799 Surround {
1800 front: (
1801 &self.attrs,
1802 &self.vis,
1803 &self.unsafety,
1804 &self.auto_token,
1805 &self.restriction,
1806 &self.trait_token,
1807 &self.ident,
1808 &self.generics,
1809 &self.colon_token,
1810 &self.supertraits,
1811 ),
1812 surround: &self.brace_token,
1813 inner: &self.items,
1814 back: (),
1815 }
1816 .locate(file_path, code, offset)
1817 }
1818}
1819
1820impl Locate for syn::ItemTraitAlias {
1821 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1822 (
1823 &self.attrs,
1824 &self.vis,
1825 &self.trait_token,
1826 &self.ident,
1827 &self.generics,
1828 &self.eq_token,
1829 &self.bounds,
1830 &self.semi_token,
1831 )
1832 .locate_as_group(file_path, code, offset)
1833 }
1834}
1835
1836impl Locate for syn::ItemType {
1837 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1838 (
1839 &self.attrs,
1840 &self.vis,
1841 &self.type_token,
1842 &self.ident,
1843 &self.generics,
1844 &self.eq_token,
1845 &self.ty,
1846 &self.semi_token,
1847 )
1848 .locate_as_group(file_path, code, offset)
1849 }
1850}
1851
1852impl Locate for syn::ItemUnion {
1853 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1854 (
1855 &self.attrs,
1856 &self.vis,
1857 &self.union_token,
1858 &self.ident,
1859 &self.generics,
1860 &self.fields,
1861 )
1862 .locate_as_group(file_path, code, offset)
1863 }
1864}
1865
1866impl Locate for syn::ItemUse {
1867 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1868 (
1869 &self.attrs,
1870 &self.vis,
1871 &self.use_token,
1872 &self.leading_colon,
1873 &self.tree,
1874 &self.semi_token,
1875 )
1876 .locate_as_group(file_path, code, offset)
1877 }
1878}
1879
1880impl Locate for syn::Label {
1881 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1882 (&self.name, &self.colon_token).locate_as_group(file_path, code, offset)
1883 }
1884}
1885
1886impl Locate for syn::Lifetime {
1887 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1888 let code = &code[offset..];
1889
1890 let start = offset
1891 + code
1892 .find('\'')
1893 .unwrap_or_else(|| panic!("expected ' from {code}"));
1894 let end = self.ident.locate(file_path, code, start + 1).end;
1895
1896 Location {
1897 file_path,
1898 start,
1899 end,
1900 }
1901 }
1902}
1903
1904impl Locate for syn::LifetimeParam {
1905 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1906 (&self.attrs, &self.lifetime, &self.colon_token, &self.bounds)
1907 .locate_as_group(file_path, code, offset)
1908 }
1909}
1910
1911impl Locate for syn::Lit {
1912 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1913 match self {
1914 Self::Str(v) => v.locate(file_path, code, offset),
1915 Self::ByteStr(v) => v.locate(file_path, code, offset),
1916 Self::CStr(v) => v.locate(file_path, code, offset),
1917 Self::Byte(v) => v.locate(file_path, code, offset),
1918 Self::Char(v) => v.locate(file_path, code, offset),
1919 Self::Int(v) => v.locate(file_path, code, offset),
1920 Self::Float(v) => v.locate(file_path, code, offset),
1921 Self::Bool(v) => v.locate(file_path, code, offset),
1922 Self::Verbatim(_) => Location {
1923 file_path,
1924 start: offset,
1925 end: offset,
1926 },
1927 _ => Location {
1928 file_path,
1929 start: offset,
1930 end: offset,
1931 },
1932 }
1933 }
1934}
1935
1936impl Locate for syn::LitStr {
1937 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1938 let lit = self.token().to_string();
1939 helper::str_location(file_path, code, offset, &lit)
1940 }
1941}
1942
1943impl Locate for syn::LitByteStr {
1944 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1945 let lit = self.token().to_string();
1946 helper::str_location(file_path, code, offset, &lit)
1947 }
1948}
1949
1950impl Locate for syn::LitCStr {
1951 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1952 let lit = self.token().to_string();
1953 helper::str_location(file_path, code, offset, &lit)
1954 }
1955}
1956
1957impl Locate for syn::LitByte {
1958 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1959 let lit = self.token().to_string();
1960 helper::str_location(file_path, code, offset, &lit)
1961 }
1962}
1963
1964impl Locate for syn::LitChar {
1965 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1966 let lit = self.token().to_string();
1967 helper::str_location(file_path, code, offset, &lit)
1968 }
1969}
1970
1971impl Locate for syn::LitInt {
1972 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1973 let lit = self.token().to_string();
1974 helper::str_location(file_path, code, offset, &lit)
1975 }
1976}
1977
1978impl Locate for syn::LitFloat {
1979 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1980 let lit = self.token().to_string();
1981 helper::str_location(file_path, code, offset, &lit)
1982 }
1983}
1984
1985impl Locate for syn::LitBool {
1986 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1987 let lit = self.token().to_string();
1988 helper::str_location(file_path, code, offset, &lit)
1989 }
1990}
1991
1992impl Locate for syn::Local {
1993 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
1994 (
1995 &self.attrs,
1996 &self.let_token,
1997 &self.pat,
1998 &self.init,
1999 &self.semi_token,
2000 )
2001 .locate_as_group(file_path, code, offset)
2002 }
2003}
2004
2005impl Locate for syn::LocalInit {
2006 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2007 if let Some((else_token, diverge)) = &self.diverge {
2008 (&self.eq_token, &self.expr, else_token, diverge)
2009 .locate_as_group(file_path, code, offset)
2010 } else {
2011 (&self.eq_token, &self.expr).locate_as_group(file_path, code, offset)
2012 }
2013 }
2014}
2015
2016impl Locate for syn::Macro {
2017 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2018 match &self.delimiter {
2019 syn::MacroDelimiter::Paren(paren) => Surround {
2020 front: (&self.path, &self.bang_token),
2021 surround: paren,
2022 inner: (),
2023 back: (),
2024 }
2025 .locate(file_path, code, offset),
2026 syn::MacroDelimiter::Brace(brace) => Surround {
2027 front: (&self.path, &self.bang_token),
2028 surround: brace,
2029 inner: (),
2030 back: (),
2031 }
2032 .locate(file_path, code, offset),
2033 syn::MacroDelimiter::Bracket(bracket) => Surround {
2034 front: (&self.path, &self.bang_token),
2035 surround: bracket,
2036 inner: (),
2037 back: (),
2038 }
2039 .locate(file_path, code, offset),
2040 }
2041 }
2042}
2043
2044impl Locate for syn::Member {
2045 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2046 match self {
2047 Self::Named(v) => v.locate(file_path, code, offset),
2048 Self::Unnamed(v) => v.locate(file_path, code, offset),
2049 }
2050 }
2051}
2052
2053impl Locate for syn::Meta {
2054 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2055 match self {
2056 Self::Path(v) => v.locate(file_path, code, offset),
2057 Self::List(v) => v.locate(file_path, code, offset),
2058 Self::NameValue(v) => v.locate(file_path, code, offset),
2059 }
2060 }
2061}
2062
2063impl Locate for syn::MetaList {
2064 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2065 match &self.delimiter {
2066 syn::MacroDelimiter::Paren(paren) => Surround {
2067 front: &self.path,
2068 surround: paren,
2069 inner: (),
2070 back: (),
2071 }
2072 .locate(file_path, code, offset),
2073 syn::MacroDelimiter::Brace(brace) => Surround {
2074 front: &self.path,
2075 surround: brace,
2076 inner: (),
2077 back: (),
2078 }
2079 .locate(file_path, code, offset),
2080 syn::MacroDelimiter::Bracket(bracket) => Surround {
2081 front: &self.path,
2082 surround: bracket,
2083 inner: (),
2084 back: (),
2085 }
2086 .locate(file_path, code, offset),
2087 }
2088 }
2089}
2090
2091impl Locate for syn::MetaNameValue {
2092 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2093 (&self.path, &self.eq_token, &self.value).locate_as_group(file_path, code, offset)
2094 }
2095}
2096
2097impl Locate for syn::ParenthesizedGenericArguments {
2098 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2099 Surround {
2100 front: (),
2101 surround: &self.paren_token,
2102 inner: &self.inputs,
2103 back: &self.output,
2104 }
2105 .locate(file_path, code, offset)
2106 }
2107}
2108
2109impl Locate for syn::Pat {
2110 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2111 match self {
2112 Self::Const(v) => v.locate(file_path, code, offset),
2113 Self::Ident(v) => v.locate(file_path, code, offset),
2114 Self::Lit(v) => v.locate(file_path, code, offset),
2115 Self::Macro(v) => v.locate(file_path, code, offset),
2116 Self::Or(v) => v.locate(file_path, code, offset),
2117 Self::Paren(v) => v.locate(file_path, code, offset),
2118 Self::Path(v) => v.locate(file_path, code, offset),
2119 Self::Range(v) => v.locate(file_path, code, offset),
2120 Self::Reference(v) => v.locate(file_path, code, offset),
2121 Self::Rest(v) => v.locate(file_path, code, offset),
2122 Self::Slice(v) => v.locate(file_path, code, offset),
2123 Self::Struct(v) => v.locate(file_path, code, offset),
2124 Self::Tuple(v) => v.locate(file_path, code, offset),
2125 Self::TupleStruct(v) => v.locate(file_path, code, offset),
2126 Self::Type(v) => v.locate(file_path, code, offset),
2127 Self::Verbatim(_) => Location {
2128 file_path,
2129 start: offset,
2130 end: offset,
2131 },
2132 Self::Wild(v) => v.locate(file_path, code, offset),
2133 _ => Location {
2134 file_path,
2135 start: offset,
2136 end: offset,
2137 },
2138 }
2139 }
2140}
2141
2142impl Locate for syn::PatIdent {
2143 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2144 if let Some((at_token, subpat)) = &self.subpat {
2145 (
2146 &self.attrs,
2147 &self.by_ref,
2148 &self.mutability,
2149 &self.ident,
2150 at_token,
2151 subpat,
2152 )
2153 .locate_as_group(file_path, code, offset)
2154 } else {
2155 (&self.attrs, &self.by_ref, &self.mutability, &self.ident)
2156 .locate_as_group(file_path, code, offset)
2157 }
2158 }
2159}
2160
2161impl Locate for syn::PatOr {
2162 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2163 (&self.attrs, &self.leading_vert, &self.cases).locate_as_group(file_path, code, offset)
2164 }
2165}
2166
2167impl Locate for syn::PatParen {
2168 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2169 Surround {
2170 front: &self.attrs,
2171 surround: &self.paren_token,
2172 inner: &self.pat,
2173 back: (),
2174 }
2175 .locate(file_path, code, offset)
2176 }
2177}
2178
2179impl Locate for syn::PatReference {
2180 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2181 (&self.attrs, &self.and_token, &self.mutability, &self.pat)
2182 .locate_as_group(file_path, code, offset)
2183 }
2184}
2185
2186impl Locate for syn::PatRest {
2187 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2188 (&self.attrs, &self.dot2_token).locate_as_group(file_path, code, offset)
2189 }
2190}
2191
2192impl Locate for syn::PatSlice {
2193 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2194 Surround {
2195 front: &self.attrs,
2196 surround: &self.bracket_token,
2197 inner: &self.elems,
2198 back: (),
2199 }
2200 .locate(file_path, code, offset)
2201 }
2202}
2203
2204impl Locate for syn::PatStruct {
2205 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2206 let front_loc = if let Some(qself) = &self.qself {
2207 Qualified {
2208 front: &self.attrs,
2209 qself,
2210 path: &self.path,
2211 back: (),
2212 }
2213 .locate(file_path, code, offset)
2214 } else {
2215 (&self.attrs, &self.path).locate_as_group(file_path, code, offset)
2216 };
2217
2218 let back_loc = Surround {
2219 front: (),
2220 surround: &self.brace_token,
2221 inner: (&self.fields, &self.rest),
2222 back: (),
2223 }
2224 .locate(file_path, code, front_loc.end);
2225
2226 Location {
2227 file_path,
2228 start: front_loc.start,
2229 end: back_loc.end,
2230 }
2231 }
2232}
2233
2234impl Locate for syn::PatTuple {
2235 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2236 Surround {
2237 front: &self.attrs,
2238 surround: &self.paren_token,
2239 inner: &self.elems,
2240 back: (),
2241 }
2242 .locate(file_path, code, offset)
2243 }
2244}
2245
2246impl Locate for syn::PatTupleStruct {
2247 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2248 let front_loc = if let Some(qself) = &self.qself {
2249 Qualified {
2250 front: &self.attrs,
2251 qself,
2252 path: &self.path,
2253 back: (),
2254 }
2255 .locate(file_path, code, offset)
2256 } else {
2257 (&self.attrs, &self.path).locate_as_group(file_path, code, offset)
2258 };
2259
2260 let back_loc = Surround {
2261 front: (),
2262 surround: &self.paren_token,
2263 inner: &self.elems,
2264 back: (),
2265 }
2266 .locate(file_path, code, front_loc.end);
2267
2268 Location {
2269 file_path,
2270 start: front_loc.start,
2271 end: back_loc.end,
2272 }
2273 }
2274}
2275
2276impl Locate for syn::PatType {
2277 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2278 (&self.attrs, &self.pat, &self.colon_token, &self.ty)
2279 .locate_as_group(file_path, code, offset)
2280 }
2281}
2282
2283impl Locate for syn::PatWild {
2284 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2285 (&self.attrs, &self.underscore_token).locate_as_group(file_path, code, offset)
2286 }
2287}
2288
2289impl Locate for syn::Path {
2290 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2291 (&self.leading_colon, &self.segments).locate_as_group(file_path, code, offset)
2292 }
2293}
2294
2295impl Locate for syn::PathArguments {
2296 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2297 match self {
2298 Self::None => Location {
2299 file_path,
2300 start: offset,
2301 end: offset,
2302 },
2303 Self::AngleBracketed(v) => v.locate(file_path, code, offset),
2304 Self::Parenthesized(v) => v.locate(file_path, code, offset),
2305 }
2306 }
2307}
2308
2309impl Locate for syn::PathSegment {
2310 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2311 (&self.ident, &self.arguments).locate_as_group(file_path, code, offset)
2312 }
2313}
2314
2315impl Locate for syn::PointerMutability {
2316 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2317 match self {
2318 Self::Const(v) => v.locate(file_path, code, offset),
2319 Self::Mut(v) => v.locate(file_path, code, offset),
2320 }
2321 }
2322}
2323
2324impl Locate for syn::PreciseCapture {
2325 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2326 (
2327 &self.use_token,
2328 &self.lt_token,
2329 &self.params,
2330 &self.gt_token,
2331 )
2332 .locate_as_group(file_path, code, offset)
2333 }
2334}
2335
2336impl Locate for syn::PredicateLifetime {
2337 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2338 (&self.lifetime, &self.colon_token, &self.bounds).locate_as_group(file_path, code, offset)
2339 }
2340}
2341
2342impl Locate for syn::PredicateType {
2343 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2344 (
2345 &self.lifetimes,
2346 &self.bounded_ty,
2347 &self.colon_token,
2348 &self.bounds,
2349 )
2350 .locate_as_group(file_path, code, offset)
2351 }
2352}
2353
2354impl Locate for syn::QSelf {
2355 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2356 let front_loc =
2357 (&self.lt_token, &self.ty, &self.as_token).locate_as_group(file_path, code, offset);
2358
2359 const OPEN: char = '<';
2360 const CLOSE: char = '>';
2361
2362 let code = &code[front_loc.end..];
2363
2364 let mut cur = front_loc.end;
2365 let mut level = 1;
2366
2367 for c in code.chars() {
2368 if c == OPEN {
2369 level += 1;
2370 } else if c == CLOSE {
2371 if level == 1 {
2372 break;
2373 }
2374 level -= 1;
2375 }
2376 cur += c.len_utf8();
2377 }
2378
2379 let end = self.gt_token.locate(file_path, code, cur).end;
2380
2381 Location {
2382 file_path,
2383 start: front_loc.start,
2384 end,
2385 }
2386 }
2387}
2388
2389impl Locate for syn::RangeLimits {
2390 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2391 match self {
2392 Self::HalfOpen(v) => v.locate(file_path, code, offset),
2393 Self::Closed(v) => v.locate(file_path, code, offset),
2394 }
2395 }
2396}
2397
2398impl Locate for syn::Receiver {
2399 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2400 if let Some((and_token, reference)) = &self.reference {
2401 (
2402 &self.attrs,
2403 and_token,
2404 reference,
2405 &self.mutability,
2406 &self.self_token,
2407 &self.colon_token,
2408 &self.ty,
2409 )
2410 .locate_as_group(file_path, code, offset)
2411 } else {
2412 (
2413 &self.attrs,
2414 &self.mutability,
2415 &self.self_token,
2416 &self.colon_token,
2417 &self.ty,
2418 )
2419 .locate_as_group(file_path, code, offset)
2420 }
2421 }
2422}
2423
2424impl Locate for syn::ReturnType {
2425 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2426 match self {
2427 Self::Default => Location {
2428 file_path,
2429 start: offset,
2430 end: offset,
2431 },
2432 Self::Type(arrow_token, ty) => {
2433 (arrow_token, ty).locate_as_group(file_path, code, offset)
2434 }
2435 }
2436 }
2437}
2438
2439impl Locate for syn::Signature {
2440 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2441 Surround {
2442 front: (
2443 &self.constness,
2444 &self.asyncness,
2445 &self.unsafety,
2446 &self.abi,
2447 &self.fn_token,
2448 &self.ident,
2449 &self.generics,
2450 ),
2451 surround: &self.paren_token,
2452 inner: (&self.inputs, &self.variadic),
2453 back: &self.output,
2454 }
2455 .locate(file_path, code, offset)
2456 }
2457}
2458
2459impl Locate for syn::StaticMutability {
2460 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2461 match self {
2462 Self::Mut(v) => v.locate(file_path, code, offset),
2463 Self::None => Location {
2464 file_path,
2465 start: offset,
2466 end: offset,
2467 },
2468 _ => Location {
2469 file_path,
2470 start: offset,
2471 end: offset,
2472 },
2473 }
2474 }
2475}
2476
2477impl Locate for syn::Stmt {
2478 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2479 match self {
2480 Self::Local(v) => v.locate(file_path, code, offset),
2481 Self::Item(v) => v.locate(file_path, code, offset),
2482 Self::Expr(expr, semi_token) => {
2483 (expr, semi_token).locate_as_group(file_path, code, offset)
2484 }
2485 Self::Macro(v) => v.locate(file_path, code, offset),
2486 }
2487 }
2488}
2489
2490impl Locate for syn::StmtMacro {
2491 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2492 (&self.attrs, &self.mac, &self.semi_token).locate_as_group(file_path, code, offset)
2493 }
2494}
2495
2496impl Locate for syn::TraitBound {
2497 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2498 (&self.modifier, &self.lifetimes, &self.path).locate_as_group(file_path, code, offset)
2500 }
2501}
2502
2503impl Locate for syn::TraitBoundModifier {
2504 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2505 match self {
2506 Self::None => Location {
2507 file_path,
2508 start: offset,
2509 end: offset,
2510 },
2511 Self::Maybe(v) => v.locate(file_path, code, offset),
2512 }
2513 }
2514}
2515
2516impl Locate for syn::TraitItem {
2517 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2518 match self {
2519 Self::Const(v) => v.locate(file_path, code, offset),
2520 Self::Fn(v) => v.locate(file_path, code, offset),
2521 Self::Type(v) => v.locate(file_path, code, offset),
2522 Self::Macro(v) => v.locate(file_path, code, offset),
2523 Self::Verbatim(_) => Location {
2524 file_path,
2525 start: offset,
2526 end: offset,
2527 },
2528 _ => Location {
2529 file_path,
2530 start: offset,
2531 end: offset,
2532 },
2533 }
2534 }
2535}
2536
2537impl Locate for syn::TraitItemConst {
2538 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2539 if let Some((eq_token, default)) = &self.default {
2540 (
2541 &self.attrs,
2542 &self.const_token,
2543 &self.ident,
2544 &self.generics,
2545 &self.colon_token,
2546 &self.ty,
2547 eq_token,
2548 default,
2549 &self.semi_token,
2550 )
2551 .locate_as_group(file_path, code, offset)
2552 } else {
2553 (
2554 &self.attrs,
2555 &self.const_token,
2556 &self.ident,
2557 &self.generics,
2558 &self.colon_token,
2559 &self.ty,
2560 &self.semi_token,
2561 )
2562 .locate_as_group(file_path, code, offset)
2563 }
2564 }
2565}
2566
2567impl Locate for syn::TraitItemFn {
2568 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2569 (&self.attrs, &self.sig, &self.default, &self.semi_token)
2570 .locate_as_group(file_path, code, offset)
2571 }
2572}
2573
2574impl Locate for syn::TraitItemType {
2575 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2576 if let Some((eq_token, default)) = &self.default {
2577 (
2578 &self.attrs,
2579 &self.type_token,
2580 &self.ident,
2581 &self.generics,
2582 &self.colon_token,
2583 &self.bounds,
2584 eq_token,
2585 default,
2586 &self.semi_token,
2587 )
2588 .locate_as_group(file_path, code, offset)
2589 } else {
2590 (
2591 &self.attrs,
2592 &self.type_token,
2593 &self.ident,
2594 &self.generics,
2595 &self.colon_token,
2596 &self.bounds,
2597 &self.semi_token,
2598 )
2599 .locate_as_group(file_path, code, offset)
2600 }
2601 }
2602}
2603
2604impl Locate for syn::TraitItemMacro {
2605 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2606 (&self.attrs, &self.mac, &self.semi_token).locate_as_group(file_path, code, offset)
2607 }
2608}
2609
2610impl Locate for syn::Type {
2611 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2612 match self {
2613 Self::Array(v) => v.locate(file_path, code, offset),
2614 Self::BareFn(v) => v.locate(file_path, code, offset),
2615 Self::Group(v) => v.locate(file_path, code, offset),
2616 Self::ImplTrait(v) => v.locate(file_path, code, offset),
2617 Self::Infer(v) => v.locate(file_path, code, offset),
2618 Self::Macro(v) => v.locate(file_path, code, offset),
2619 Self::Never(v) => v.locate(file_path, code, offset),
2620 Self::Paren(v) => v.locate(file_path, code, offset),
2621 Self::Path(v) => v.locate(file_path, code, offset),
2622 Self::Ptr(v) => v.locate(file_path, code, offset),
2623 Self::Reference(v) => v.locate(file_path, code, offset),
2624 Self::Slice(v) => v.locate(file_path, code, offset),
2625 Self::TraitObject(v) => v.locate(file_path, code, offset),
2626 Self::Tuple(v) => v.locate(file_path, code, offset),
2627 Self::Verbatim(_) => Location {
2628 file_path,
2629 start: offset,
2630 end: offset,
2631 },
2632 _ => Location {
2633 file_path,
2634 start: offset,
2635 end: offset,
2636 },
2637 }
2638 }
2639}
2640
2641impl Locate for syn::TypeArray {
2642 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2643 Surround {
2644 front: (),
2645 surround: &self.bracket_token,
2646 inner: (&self.elem, &self.semi_token, &self.len),
2647 back: (),
2648 }
2649 .locate(file_path, code, offset)
2650 }
2651}
2652
2653impl Locate for syn::TypeBareFn {
2654 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2655 Surround {
2656 front: (&self.lifetimes, &self.unsafety, &self.abi, &self.fn_token),
2657 surround: &self.paren_token,
2658 inner: (&self.inputs, &self.variadic),
2659 back: &self.output,
2660 }
2661 .locate(file_path, code, offset)
2662 }
2663}
2664
2665impl Locate for syn::TypeGroup {
2666 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2667 (&self.group_token, &self.elem).locate_as_group(file_path, code, offset)
2668 }
2669}
2670
2671impl Locate for syn::TypeImplTrait {
2672 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2673 (&self.impl_token, &self.bounds).locate_as_group(file_path, code, offset)
2674 }
2675}
2676
2677impl Locate for syn::TypeInfer {
2678 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2679 self.underscore_token.locate(file_path, code, offset)
2680 }
2681}
2682
2683impl Locate for syn::TypeMacro {
2684 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2685 self.mac.locate(file_path, code, offset)
2686 }
2687}
2688
2689impl Locate for syn::TypeNever {
2690 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2691 self.bang_token.locate(file_path, code, offset)
2692 }
2693}
2694
2695impl Locate for syn::TypeParen {
2696 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2697 Surround {
2698 front: (),
2699 surround: &self.paren_token,
2700 inner: &self.elem,
2701 back: (),
2702 }
2703 .locate(file_path, code, offset)
2704 }
2705}
2706
2707impl Locate for syn::TypePath {
2708 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2709 if let Some(qself) = &self.qself {
2710 Qualified {
2711 front: (),
2712 qself,
2713 path: &self.path,
2714 back: (),
2715 }
2716 .locate(file_path, code, offset)
2717 } else {
2718 self.path.locate(file_path, code, offset)
2719 }
2720 }
2721}
2722
2723impl Locate for syn::TypePtr {
2724 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2725 (
2726 &self.star_token,
2727 &self.const_token,
2728 &self.mutability,
2729 &self.elem,
2730 )
2731 .locate_as_group(file_path, code, offset)
2732 }
2733}
2734
2735impl Locate for syn::TypeReference {
2736 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2737 (
2738 &self.and_token,
2739 &self.lifetime,
2740 &self.mutability,
2741 &self.elem,
2742 )
2743 .locate_as_group(file_path, code, offset)
2744 }
2745}
2746
2747impl Locate for syn::TypeSlice {
2748 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2749 Surround {
2750 front: (),
2751 surround: &self.bracket_token,
2752 inner: &self.elem,
2753 back: (),
2754 }
2755 .locate(file_path, code, offset)
2756 }
2757}
2758
2759impl Locate for syn::TypeTraitObject {
2760 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2761 (&self.dyn_token, &self.bounds).locate_as_group(file_path, code, offset)
2762 }
2763}
2764
2765impl Locate for syn::TypeTuple {
2766 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2767 Surround {
2768 front: (),
2769 surround: &self.paren_token,
2770 inner: &self.elems,
2771 back: (),
2772 }
2773 .locate(file_path, code, offset)
2774 }
2775}
2776
2777impl Locate for syn::TypeParam {
2778 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2779 (
2780 &self.attrs,
2781 &self.ident,
2782 &self.colon_token,
2783 &self.bounds,
2784 &self.eq_token,
2785 &self.default,
2786 )
2787 .locate_as_group(file_path, code, offset)
2788 }
2789}
2790
2791impl Locate for syn::TypeParamBound {
2792 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2793 match self {
2794 Self::Trait(v) => v.locate(file_path, code, offset),
2795 Self::Lifetime(v) => v.locate(file_path, code, offset),
2796 Self::PreciseCapture(v) => v.locate(file_path, code, offset),
2797 Self::Verbatim(_) => Location {
2798 file_path,
2799 start: offset,
2800 end: offset,
2801 },
2802 _ => Location {
2803 file_path,
2804 start: offset,
2805 end: offset,
2806 },
2807 }
2808 }
2809}
2810
2811impl Locate for syn::UnOp {
2812 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2813 match self {
2814 Self::Deref(v) => v.locate(file_path, code, offset),
2815 Self::Not(v) => v.locate(file_path, code, offset),
2816 Self::Neg(v) => v.locate(file_path, code, offset),
2817 _ => Location {
2818 file_path,
2819 start: offset,
2820 end: offset,
2821 },
2822 }
2823 }
2824}
2825
2826impl Locate for syn::UseGlob {
2827 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2828 self.star_token.locate(file_path, code, offset)
2829 }
2830}
2831
2832impl Locate for syn::UseGroup {
2833 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2834 Surround {
2835 front: (),
2836 surround: &self.brace_token,
2837 inner: &self.items,
2838 back: (),
2839 }
2840 .locate(file_path, code, offset)
2841 }
2842}
2843
2844impl Locate for syn::UseName {
2845 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2846 self.ident.locate(file_path, code, offset)
2847 }
2848}
2849
2850impl Locate for syn::UsePath {
2851 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2852 (&self.ident, &self.colon2_token, &self.tree).locate_as_group(file_path, code, offset)
2853 }
2854}
2855
2856impl Locate for syn::UseRename {
2857 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2858 (&self.ident, &self.as_token, &self.rename).locate_as_group(file_path, code, offset)
2859 }
2860}
2861
2862impl Locate for syn::UseTree {
2863 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2864 match self {
2865 Self::Path(v) => v.locate(file_path, code, offset),
2866 Self::Name(v) => v.locate(file_path, code, offset),
2867 Self::Rename(v) => v.locate(file_path, code, offset),
2868 Self::Glob(v) => v.locate(file_path, code, offset),
2869 Self::Group(v) => v.locate(file_path, code, offset),
2870 }
2871 }
2872}
2873
2874impl Locate for syn::Variadic {
2875 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2876 if let Some((pat, colon_token)) = &self.pat {
2877 (&self.attrs, pat, colon_token, &self.dots, &self.comma)
2878 .locate_as_group(file_path, code, offset)
2879 } else {
2880 (&self.attrs, &self.dots, &self.comma).locate_as_group(file_path, code, offset)
2881 }
2882 }
2883}
2884
2885impl Locate for syn::Variant {
2886 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2887 if let Some((eq_token, discriminant)) = &self.discriminant {
2888 (
2889 &self.attrs,
2890 &self.ident,
2891 &self.fields,
2892 eq_token,
2893 discriminant,
2894 )
2895 .locate_as_group(file_path, code, offset)
2896 } else {
2897 (&self.attrs, &self.ident, &self.fields).locate_as_group(file_path, code, offset)
2898 }
2899 }
2900}
2901
2902impl Locate for syn::Visibility {
2903 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2904 match self {
2905 Self::Public(v) => v.locate(file_path, code, offset),
2906 Self::Restricted(v) => v.locate(file_path, code, offset),
2907 Self::Inherited => Location {
2908 file_path,
2909 start: offset,
2910 end: offset,
2911 },
2912 }
2913 }
2914}
2915
2916impl Locate for syn::VisRestricted {
2917 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2918 Surround {
2919 front: &self.pub_token,
2920 surround: &self.paren_token,
2921 inner: (&self.in_token, &self.path),
2922 back: (),
2923 }
2924 .locate(file_path, code, offset)
2925 }
2926}
2927
2928impl Locate for syn::WhereClause {
2929 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2930 (&self.where_token, &self.predicates).locate_as_group(file_path, code, offset)
2931 }
2932}
2933
2934impl Locate for syn::WherePredicate {
2935 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2936 match self {
2937 Self::Lifetime(v) => v.locate(file_path, code, offset),
2938 Self::Type(v) => v.locate(file_path, code, offset),
2939 _ => Location {
2940 file_path,
2941 start: offset,
2942 end: offset,
2943 },
2944 }
2945 }
2946}
2947
2948impl<T: Locate> Locate for Option<T> {
2951 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2952 if let Some(inner) = self {
2953 inner.locate(file_path, code, offset)
2954 } else {
2955 Location {
2956 file_path,
2957 start: offset,
2958 end: offset,
2959 }
2960 }
2961 }
2962}
2963
2964impl<T: Locate> Locate for Box<T> {
2965 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2966 let t = &**self;
2967 t.locate(file_path, code, offset)
2968 }
2969}
2970
2971impl<T: Locate> Locate for Vec<T> {
2972 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2973 let mut start = usize::MAX;
2974 let mut end = offset;
2975
2976 for item in self {
2977 let loc = item.locate(file_path, code, end);
2978 start = start.min(loc.start);
2979 end = loc.end;
2980 }
2981
2982 Location {
2983 file_path,
2984 start: if start != usize::MAX { start } else { offset },
2985 end,
2986 }
2987 }
2988}
2989
2990impl<T, S> Locate for syn::punctuated::Punctuated<T, S>
2991where
2992 T: Locate,
2993 S: Locate,
2994{
2995 fn find_loc(&self, file_path: &'static str, code: &str, offset: usize) -> Location {
2996 let mut start = usize::MAX;
2997 let mut end = offset;
2998
2999 for item in self {
3000 let loc = item.locate(file_path, code, end);
3001 start = start.min(loc.start);
3002 end = loc.end;
3003 }
3004
3005 Location {
3006 file_path,
3007 start: if start != usize::MAX { start } else { offset },
3008 end,
3009 }
3010 }
3011}
3012
3013pub mod helper {
3016 use super::*;
3017
3018 pub fn char_location(
3019 file_path: &'static str,
3020 code: &str,
3021 offset: usize,
3022 content: char,
3023 ) -> Location {
3024 let code = &code[offset..];
3025 let start = offset
3026 + code
3027 .find(content)
3028 .unwrap_or_else(|| panic!("expected `{content}` from `{code}`"));
3029
3030 Location {
3031 file_path,
3032 start,
3033 end: start + content.len_utf8(),
3034 }
3035 }
3036
3037 pub fn str_location(
3038 file_path: &'static str,
3039 code: &str,
3040 offset: usize,
3041 content: &str,
3042 ) -> Location {
3043 let code = &code[offset..];
3044
3045 let start = offset
3046 + code
3047 .find(content)
3048 .unwrap_or_else(|| panic!("expected `{content}` from `{code}`"));
3049
3050 Location {
3051 file_path,
3052 start,
3053 end: start + content.len(),
3054 }
3055 }
3056}