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