dprint_swc_ext/common/
comments.rs1use super::pos::*;
2use super::text_info::*;
3use super::tokens::*;
4use crate::swc::common::comments::Comment;
5use crate::swc::common::comments::SingleThreadedCommentsMapInner;
6
7pub struct CommentContainer<'a> {
8 pub leading: &'a SingleThreadedCommentsMapInner,
9 pub trailing: &'a SingleThreadedCommentsMapInner,
10 tokens: &'a TokenContainer<'a>,
11 text_info: &'a SourceTextInfo,
12}
13
14impl<'a> CommentContainer<'a> {
15 pub fn new(
16 leading: &'a SingleThreadedCommentsMapInner,
17 trailing: &'a SingleThreadedCommentsMapInner,
18 tokens: &'a TokenContainer<'a>,
19 text_info: &'a SourceTextInfo,
20 ) -> Self {
21 CommentContainer {
22 leading,
23 trailing,
24 tokens,
25 text_info,
26 }
27 }
28
29 pub fn all_comments(&'a self) -> CommentsIterator<'a> {
30 let approx_cap = self.leading.len() + self.trailing.len();
31 let mut v = Vec::with_capacity(approx_cap);
32 v.extend(self.leading.values());
33 v.extend(self.trailing.values());
34 CommentsIterator::new(v)
35 }
36
37 pub fn leading_comments(&'a self, start: SourcePos) -> CommentsIterator<'a> {
38 let previous_token_hi = self.tokens.get_token_index_at_start(start).map(|index| {
39 if index == 0 {
40 self.text_info.range().start.as_source_pos()
41 } else {
42 self.tokens.get_token_at_index(index - 1).unwrap().end()
43 }
44 });
45 let leading = self.get_leading(start);
46 if let Some(previous_token_hi) = previous_token_hi {
47 let trailing = self.get_trailing(previous_token_hi);
48 combine_comment_vecs(trailing, leading)
49 } else {
50 leading.map(|l| CommentsIterator::new(vec![l])).unwrap_or_default()
51 }
52 }
53
54 pub fn trailing_comments(&'a self, end: SourcePos) -> CommentsIterator<'a> {
55 let next_token_lo = self.tokens.get_token_index_at_end(end).map(|index| {
56 self
57 .tokens
58 .get_token_at_index(index + 1)
59 .map(|t| t.start())
60 .unwrap_or_else(|| self.text_info.range().end)
61 });
62 let trailing = self.get_trailing(end);
63 if let Some(next_token_lo) = next_token_lo {
64 let leading = self.get_leading(next_token_lo);
65 combine_comment_vecs(trailing, leading)
66 } else {
67 trailing.map(|t| CommentsIterator::new(vec![t])).unwrap_or_default()
68 }
69 }
70
71 fn get_leading(&'a self, start: SourcePos) -> Option<&'a Vec<Comment>> {
72 self.leading.get(&start.as_byte_pos())
73 }
74
75 fn get_trailing(&'a self, end: SourcePos) -> Option<&'a Vec<Comment>> {
76 self.trailing.get(&end.as_byte_pos())
77 }
78}
79
80fn combine_comment_vecs<'a>(a: Option<&'a Vec<Comment>>, b: Option<&'a Vec<Comment>>) -> CommentsIterator<'a> {
81 let length = if a.is_some() { 1 } else { 0 } + if b.is_some() { 1 } else { 0 };
82 let mut comment_vecs = Vec::with_capacity(length);
83 if let Some(a) = a {
84 comment_vecs.push(a);
85 }
86 if let Some(b) = b {
87 comment_vecs.push(b);
88 }
89 CommentsIterator::new(comment_vecs)
90}
91
92#[derive(Clone)]
93pub struct CommentsIterator<'a> {
94 comment_vecs: Vec<&'a Vec<Comment>>,
95 outer_index: usize,
96 inner_index: usize,
97 outer_index_back: usize,
98 inner_index_back: usize,
99}
100
101impl<'a> CommentsIterator<'a> {
102 pub fn empty() -> Self {
103 Self::new(Vec::with_capacity(0))
104 }
105
106 pub fn new(comment_vecs: Vec<&'a Vec<Comment>>) -> Self {
107 let outer_index_back = comment_vecs.len();
108 CommentsIterator {
109 comment_vecs,
110 outer_index: 0,
111 inner_index: 0,
112 outer_index_back,
113 inner_index_back: 0,
114 }
115 }
116
117 pub fn reset(&mut self) {
118 self.outer_index = 0;
119 self.inner_index = 0;
120 }
121
122 pub fn extend(&mut self, iterator: CommentsIterator<'a>) {
123 self.comment_vecs.extend(iterator.comment_vecs);
124
125 self.outer_index_back = self.comment_vecs.len();
127 self.inner_index_back = 0;
128 }
129
130 pub fn is_empty(&self) -> bool {
131 for comments in self.comment_vecs.iter() {
132 if !comments.is_empty() {
133 return false;
134 }
135 }
136
137 true
138 }
139
140 pub fn peek_last_comment(&self) -> Option<&'a Comment> {
141 if let Some(comments) = self.comment_vecs.last() {
142 comments.last()
143 } else {
144 None
145 }
146 }
147}
148
149impl<'a> Default for CommentsIterator<'a> {
150 fn default() -> Self {
151 Self::empty()
152 }
153}
154
155impl<'a> Iterator for CommentsIterator<'a> {
156 type Item = &'a Comment;
157
158 fn next(&mut self) -> Option<&'a Comment> {
159 loop {
160 if let Some(comments) = self.comment_vecs.get(self.outer_index) {
161 if let Some(comment) = comments.get(self.inner_index) {
162 self.inner_index += 1;
163 return Some(comment);
164 } else {
165 self.inner_index = 0;
166 self.outer_index += 1;
167 }
168 } else {
169 return None;
170 }
171 }
172 }
173
174 fn size_hint(&self) -> (usize, Option<usize>) {
175 let mut next_inner_index = self.inner_index;
176 let mut count = 0;
177 for comment_vec in &self.comment_vecs[self.outer_index..] {
178 count += comment_vec.len() - next_inner_index;
179 next_inner_index = 0;
180 }
181 (count, Some(count))
182 }
183}
184
185impl<'a> DoubleEndedIterator for CommentsIterator<'a> {
186 fn next_back(&mut self) -> Option<&'a Comment> {
187 if self.inner_index_back == 0 {
188 if self.outer_index_back == 0 {
189 return None;
190 }
191 self.outer_index_back -= 1;
192 self.inner_index_back = self.comment_vecs.get(self.outer_index_back).unwrap().len() - 1;
193 } else {
194 self.inner_index_back -= 1;
195 }
196
197 self.comment_vecs.get(self.outer_index_back).and_then(|inner| inner.get(self.inner_index_back))
198 }
199}