1use crate::priv_prelude::*;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
4pub enum Spacing {
5 Joint,
6 Alone,
7}
8
9#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
10pub struct Punct {
11 pub span: Span,
12 pub kind: PunctKind,
13 pub spacing: Spacing,
14}
15
16impl Spanned for Punct {
17 fn span(&self) -> Span {
18 self.span.clone()
19 }
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
23pub struct GenericGroup<T> {
24 pub delimiter: Delimiter,
25 pub token_stream: T,
26 pub span: Span,
27}
28
29pub type Group = GenericGroup<TokenStream>;
30pub type CommentedGroup = GenericGroup<CommentedTokenStream>;
31
32impl<T> Spanned for GenericGroup<T> {
33 fn span(&self) -> Span {
34 self.span.clone()
35 }
36}
37
38#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
39pub enum CommentKind {
40 Newlined,
51
52 Trailing,
60
61 Inlined,
69
70 Multilined,
79}
80
81#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
82pub struct Comment {
83 pub span: Span,
84 pub comment_kind: CommentKind,
85}
86
87impl Spanned for Comment {
88 fn span(&self) -> Span {
89 self.span.clone()
90 }
91}
92
93#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
94pub enum DocStyle {
95 Outer,
96 Inner,
97}
98
99#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
100pub struct DocComment {
101 pub span: Span,
102 pub content_span: Span,
103 pub doc_style: DocStyle,
104}
105
106impl Spanned for DocComment {
107 fn span(&self) -> Span {
108 self.span.clone()
109 }
110}
111
112#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
114pub enum GenericTokenTree<T> {
115 Punct(Punct),
116 Ident(Ident),
117 Group(GenericGroup<T>),
118 Literal(Literal),
119 DocComment(DocComment),
120}
121
122pub type TokenTree = GenericTokenTree<TokenStream>;
123pub type CommentedTree = GenericTokenTree<CommentedTokenStream>;
124
125#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
126pub enum CommentedTokenTree {
127 Comment(Comment),
128 Tree(CommentedTree),
129}
130
131impl CommentedGroup {
132 pub fn strip_comments(self) -> Group {
133 Group {
134 delimiter: self.delimiter,
135 token_stream: self.token_stream.strip_comments(),
136 span: self.span,
137 }
138 }
139}
140
141impl<T> Spanned for GenericTokenTree<T> {
142 fn span(&self) -> Span {
143 match self {
144 Self::Punct(punct) => punct.span(),
145 Self::Ident(ident) => ident.span(),
146 Self::Group(group) => group.span(),
147 Self::Literal(literal) => literal.span(),
148 Self::DocComment(doc_comment) => doc_comment.span(),
149 }
150 }
151}
152
153impl Spanned for CommentedTokenTree {
154 fn span(&self) -> Span {
155 match self {
156 Self::Comment(cmt) => cmt.span(),
157 Self::Tree(tt) => tt.span(),
158 }
159 }
160}
161
162impl<T> From<Punct> for GenericTokenTree<T> {
163 fn from(punct: Punct) -> Self {
164 Self::Punct(punct)
165 }
166}
167
168impl<T> From<Ident> for GenericTokenTree<T> {
169 fn from(ident: Ident) -> Self {
170 Self::Ident(ident)
171 }
172}
173
174impl<T> From<GenericGroup<T>> for GenericTokenTree<T> {
175 fn from(group: GenericGroup<T>) -> Self {
176 Self::Group(group)
177 }
178}
179
180impl<T> From<Literal> for GenericTokenTree<T> {
181 fn from(lit: Literal) -> Self {
182 Self::Literal(lit)
183 }
184}
185
186impl<T> From<DocComment> for GenericTokenTree<T> {
187 fn from(doc_comment: DocComment) -> Self {
188 Self::DocComment(doc_comment)
189 }
190}
191
192impl From<Comment> for CommentedTokenTree {
193 fn from(comment: Comment) -> Self {
194 Self::Comment(comment)
195 }
196}
197
198impl From<CommentedTree> for CommentedTokenTree {
199 fn from(tree: CommentedTree) -> Self {
200 Self::Tree(tree)
201 }
202}
203
204#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
205pub struct TokenStream {
206 token_trees: Vec<TokenTree>,
207 full_span: Span,
208}
209
210#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
211pub struct CommentedTokenStream {
212 pub token_trees: Vec<CommentedTokenTree>,
213 pub full_span: Span,
214}
215
216#[extension_trait]
217impl CharExt for char {
218 fn as_open_delimiter(self) -> Option<Delimiter> {
219 match self {
220 '(' => Some(Delimiter::Parenthesis),
221 '{' => Some(Delimiter::Brace),
222 '[' => Some(Delimiter::Bracket),
223 _ => None,
224 }
225 }
226
227 fn as_close_delimiter(self) -> Option<Delimiter> {
228 match self {
229 ')' => Some(Delimiter::Parenthesis),
230 '}' => Some(Delimiter::Brace),
231 ']' => Some(Delimiter::Bracket),
232 _ => None,
233 }
234 }
235
236 fn as_punct_kind(self) -> Option<PunctKind> {
237 match self {
238 ';' => Some(PunctKind::Semicolon),
239 ':' => Some(PunctKind::Colon),
240 '/' => Some(PunctKind::ForwardSlash),
241 ',' => Some(PunctKind::Comma),
242 '*' => Some(PunctKind::Star),
243 '+' => Some(PunctKind::Add),
244 '-' => Some(PunctKind::Sub),
245 '<' => Some(PunctKind::LessThan),
246 '>' => Some(PunctKind::GreaterThan),
247 '=' => Some(PunctKind::Equals),
248 '.' => Some(PunctKind::Dot),
249 '!' => Some(PunctKind::Bang),
250 '%' => Some(PunctKind::Percent),
251 '&' => Some(PunctKind::Ampersand),
252 '^' => Some(PunctKind::Caret),
253 '|' => Some(PunctKind::Pipe),
254 '_' => Some(PunctKind::Underscore),
255 '#' => Some(PunctKind::Sharp),
256 _ => None,
257 }
258 }
259}
260
261impl TokenStream {
262 pub fn token_trees(&self) -> &[TokenTree] {
263 &self.token_trees
264 }
265}
266
267impl Spanned for TokenStream {
268 fn span(&self) -> Span {
269 self.full_span.clone()
270 }
271}
272
273impl CommentedTokenTree {
274 pub fn strip_comments(self) -> Option<TokenTree> {
275 let commented_tt = match self {
276 Self::Comment(_) => return None,
277 Self::Tree(commented_tt) => commented_tt,
278 };
279 let tt = match commented_tt {
280 CommentedTree::Punct(punct) => punct.into(),
281 CommentedTree::Ident(ident) => ident.into(),
282 CommentedTree::Group(group) => group.strip_comments().into(),
283 CommentedTree::Literal(lit) => lit.into(),
284 CommentedTree::DocComment(doc_comment) => doc_comment.into(),
285 };
286 Some(tt)
287 }
288}
289
290impl CommentedTokenStream {
291 pub fn token_trees(&self) -> &[CommentedTokenTree] {
292 &self.token_trees
293 }
294
295 pub fn strip_comments(self) -> TokenStream {
296 let token_trees = self
297 .token_trees
298 .into_iter()
299 .filter_map(|tree| tree.strip_comments())
300 .collect();
301 TokenStream {
302 token_trees,
303 full_span: self.full_span,
304 }
305 }
306}
307
308impl Spanned for CommentedTokenStream {
309 fn span(&self) -> Span {
310 self.full_span.clone()
311 }
312}