blob: b981f321ce5229e7c9fe2443e9dafd3dc2fde196 [file] [log] [blame]
David Tolnay55535012018-01-05 16:39:23 -08001// Copyright 2018 Syn Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
David Tolnayf60f4262017-12-28 19:17:58 -05009#[cfg(feature = "fold")]
10pub mod fold {
David Tolnay61037c62018-01-05 16:21:03 -080011 use punctuated::{Element, Punctuated};
David Tolnay4b4c4b62018-01-06 13:48:05 -080012 use fold::Fold;
David Tolnaycc0f0372017-12-28 19:11:04 -050013 use proc_macro2::Span;
David Tolnayf60f4262017-12-28 19:17:58 -050014
15 pub trait FoldHelper {
16 type Item;
David Tolnay61037c62018-01-05 16:21:03 -080017 fn lift<F>(self, f: F) -> Self
18 where
19 F: FnMut(Self::Item) -> Self::Item;
David Tolnayf60f4262017-12-28 19:17:58 -050020 }
21
22 impl<T> FoldHelper for Vec<T> {
23 type Item = T;
David Tolnay61037c62018-01-05 16:21:03 -080024 fn lift<F>(self, f: F) -> Self
25 where
26 F: FnMut(Self::Item) -> Self::Item,
27 {
David Tolnayf60f4262017-12-28 19:17:58 -050028 self.into_iter().map(f).collect()
29 }
30 }
31
David Tolnayf2cfd722017-12-31 18:02:51 -050032 impl<T, U> FoldHelper for Punctuated<T, U> {
David Tolnayf60f4262017-12-28 19:17:58 -050033 type Item = T;
David Tolnay61037c62018-01-05 16:21:03 -080034 fn lift<F>(self, mut f: F) -> Self
35 where
36 F: FnMut(Self::Item) -> Self::Item,
37 {
David Tolnay6eff4da2018-01-01 20:27:45 -080038 self.into_elements()
David Tolnay660fd1f2017-12-31 01:52:57 -050039 .map(Element::into_tuple)
40 .map(|(t, u)| Element::new(f(t), u))
41 .collect()
David Tolnayf60f4262017-12-28 19:17:58 -050042 }
43 }
David Tolnaycc0f0372017-12-28 19:11:04 -050044
David Tolnay4b4c4b62018-01-06 13:48:05 -080045 pub fn tokens_helper<F: Fold + ?Sized, S: Spans>(folder: &mut F, spans: &S) -> S {
David Tolnaycc0f0372017-12-28 19:11:04 -050046 spans.fold(folder)
47 }
48
49 pub trait Spans {
David Tolnay4b4c4b62018-01-06 13:48:05 -080050 fn fold<F: Fold + ?Sized>(&self, folder: &mut F) -> Self;
David Tolnaycc0f0372017-12-28 19:11:04 -050051 }
52
53 impl Spans for Span {
David Tolnay4b4c4b62018-01-06 13:48:05 -080054 fn fold<F: Fold + ?Sized>(&self, folder: &mut F) -> Self {
David Tolnaycc0f0372017-12-28 19:11:04 -050055 folder.fold_span(*self)
56 }
57 }
58
59 impl Spans for [Span; 1] {
David Tolnay4b4c4b62018-01-06 13:48:05 -080060 fn fold<F: Fold + ?Sized>(&self, folder: &mut F) -> Self {
David Tolnaycc0f0372017-12-28 19:11:04 -050061 [folder.fold_span(self[0])]
62 }
63 }
64
65 impl Spans for [Span; 2] {
David Tolnay4b4c4b62018-01-06 13:48:05 -080066 fn fold<F: Fold + ?Sized>(&self, folder: &mut F) -> Self {
David Tolnaycc0f0372017-12-28 19:11:04 -050067 [folder.fold_span(self[0]), folder.fold_span(self[1])]
68 }
69 }
70
71 impl Spans for [Span; 3] {
David Tolnay4b4c4b62018-01-06 13:48:05 -080072 fn fold<F: Fold + ?Sized>(&self, folder: &mut F) -> Self {
David Tolnay61037c62018-01-05 16:21:03 -080073 [
74 folder.fold_span(self[0]),
75 folder.fold_span(self[1]),
76 folder.fold_span(self[2]),
77 ]
David Tolnaycc0f0372017-12-28 19:11:04 -050078 }
79 }
80}
81
82#[cfg(feature = "visit")]
83pub mod visit {
84 use proc_macro2::Span;
David Tolnay4b4c4b62018-01-06 13:48:05 -080085 use visit::Visit;
David Tolnaycc0f0372017-12-28 19:11:04 -050086
David Tolnay4b4c4b62018-01-06 13:48:05 -080087 pub fn tokens_helper<'ast, V: Visit<'ast> + ?Sized, S: Spans>(
David Tolnay61037c62018-01-05 16:21:03 -080088 visitor: &mut V,
89 spans: &'ast S,
90 ) {
David Tolnaycc0f0372017-12-28 19:11:04 -050091 spans.visit(visitor);
92 }
93
94 pub trait Spans {
David Tolnay4b4c4b62018-01-06 13:48:05 -080095 fn visit<'ast, V: Visit<'ast> + ?Sized>(&'ast self, visitor: &mut V);
David Tolnaycc0f0372017-12-28 19:11:04 -050096 }
97
98 impl Spans for Span {
David Tolnay4b4c4b62018-01-06 13:48:05 -080099 fn visit<'ast, V: Visit<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500100 visitor.visit_span(self);
101 }
102 }
103
104 impl Spans for [Span; 1] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800105 fn visit<'ast, V: Visit<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500106 visitor.visit_span(&self[0]);
107 }
108 }
109
110 impl Spans for [Span; 2] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800111 fn visit<'ast, V: Visit<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500112 visitor.visit_span(&self[0]);
113 visitor.visit_span(&self[1]);
114 }
115 }
116
117 impl Spans for [Span; 3] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800118 fn visit<'ast, V: Visit<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500119 visitor.visit_span(&self[0]);
120 visitor.visit_span(&self[1]);
121 visitor.visit_span(&self[2]);
122 }
123 }
124}
125
David Tolnay9df02c42018-01-06 13:52:48 -0800126#[cfg(feature = "visit-mut")]
David Tolnaycc0f0372017-12-28 19:11:04 -0500127pub mod visit_mut {
128 use proc_macro2::Span;
David Tolnay4b4c4b62018-01-06 13:48:05 -0800129 use visit_mut::VisitMut;
David Tolnaycc0f0372017-12-28 19:11:04 -0500130
David Tolnay4b4c4b62018-01-06 13:48:05 -0800131 pub fn tokens_helper<V: VisitMut + ?Sized, S: Spans>(visitor: &mut V, spans: &mut S) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500132 spans.visit_mut(visitor);
133 }
134
135 pub trait Spans {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800136 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V);
David Tolnaycc0f0372017-12-28 19:11:04 -0500137 }
138
139 impl Spans for Span {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800140 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500141 visitor.visit_span_mut(self);
142 }
143 }
144
145 impl Spans for [Span; 1] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800146 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500147 visitor.visit_span_mut(&mut self[0]);
148 }
149 }
150
151 impl Spans for [Span; 2] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800152 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500153 visitor.visit_span_mut(&mut self[0]);
154 visitor.visit_span_mut(&mut self[1]);
155 }
156 }
157
158 impl Spans for [Span; 3] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800159 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500160 visitor.visit_span_mut(&mut self[0]);
161 visitor.visit_span_mut(&mut self[1]);
162 visitor.visit_span_mut(&mut self[2]);
163 }
164 }
David Tolnayf60f4262017-12-28 19:17:58 -0500165}