blob: fe00c8f78ecc750bd1a86a910632789783862e0c [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 Tolnay4b4c4b62018-01-06 13:48:05 -080011 use fold::Fold;
David Tolnaycc0f0372017-12-28 19:11:04 -050012 use proc_macro2::Span;
David Tolnay94d2b792018-04-29 12:26:10 -070013 use punctuated::{Pair, Punctuated};
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 Tolnay56080682018-01-06 14:01:52 -080038 self.into_pairs()
39 .map(Pair::into_tuple)
40 .map(|(t, u)| Pair::new(f(t), u))
David Tolnay660fd1f2017-12-31 01:52:57 -050041 .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 Tolnay94d2b792018-04-29 12:26:10 -070087 pub fn tokens_helper<'ast, V: Visit<'ast> + ?Sized, S: Spans>(visitor: &mut V, spans: &'ast S) {
David Tolnaycc0f0372017-12-28 19:11:04 -050088 spans.visit(visitor);
89 }
90
91 pub trait Spans {
David Tolnay4b4c4b62018-01-06 13:48:05 -080092 fn visit<'ast, V: Visit<'ast> + ?Sized>(&'ast self, visitor: &mut V);
David Tolnaycc0f0372017-12-28 19:11:04 -050093 }
94
95 impl Spans for Span {
David Tolnay4b4c4b62018-01-06 13:48:05 -080096 fn visit<'ast, V: Visit<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -050097 visitor.visit_span(self);
98 }
99 }
100
101 impl Spans for [Span; 1] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800102 fn visit<'ast, V: Visit<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500103 visitor.visit_span(&self[0]);
104 }
105 }
106
107 impl Spans for [Span; 2] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800108 fn visit<'ast, V: Visit<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500109 visitor.visit_span(&self[0]);
110 visitor.visit_span(&self[1]);
111 }
112 }
113
114 impl Spans for [Span; 3] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800115 fn visit<'ast, V: Visit<'ast> + ?Sized>(&'ast self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500116 visitor.visit_span(&self[0]);
117 visitor.visit_span(&self[1]);
118 visitor.visit_span(&self[2]);
119 }
120 }
121}
122
David Tolnay9df02c42018-01-06 13:52:48 -0800123#[cfg(feature = "visit-mut")]
David Tolnaycc0f0372017-12-28 19:11:04 -0500124pub mod visit_mut {
125 use proc_macro2::Span;
David Tolnay4b4c4b62018-01-06 13:48:05 -0800126 use visit_mut::VisitMut;
David Tolnaycc0f0372017-12-28 19:11:04 -0500127
David Tolnay4b4c4b62018-01-06 13:48:05 -0800128 pub fn tokens_helper<V: VisitMut + ?Sized, S: Spans>(visitor: &mut V, spans: &mut S) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500129 spans.visit_mut(visitor);
130 }
131
132 pub trait Spans {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800133 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V);
David Tolnaycc0f0372017-12-28 19:11:04 -0500134 }
135
136 impl Spans for Span {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800137 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500138 visitor.visit_span_mut(self);
139 }
140 }
141
142 impl Spans for [Span; 1] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800143 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500144 visitor.visit_span_mut(&mut self[0]);
145 }
146 }
147
148 impl Spans for [Span; 2] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800149 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500150 visitor.visit_span_mut(&mut self[0]);
151 visitor.visit_span_mut(&mut self[1]);
152 }
153 }
154
155 impl Spans for [Span; 3] {
David Tolnay4b4c4b62018-01-06 13:48:05 -0800156 fn visit_mut<V: VisitMut + ?Sized>(&mut self, visitor: &mut V) {
David Tolnaycc0f0372017-12-28 19:11:04 -0500157 visitor.visit_span_mut(&mut self[0]);
158 visitor.visit_span_mut(&mut self[1]);
159 visitor.visit_span_mut(&mut self[2]);
160 }
161 }
David Tolnayf60f4262017-12-28 19:17:58 -0500162}