| 1 | |
| 2 |
|
| 3 | |
| 4 | |
| 5 |
|
| 6 | |
| 7 | |
| 8 | |
| 9 |
|
| 10 | use crate::Lifetime;
|
| 11 | use proc_macro2::extra::DelimSpan;
|
| 12 | use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
|
| 13 | use std::cmp::Ordering;
|
| 14 | use std::marker::PhantomData;
|
| 15 | use std::ptr;
|
| 16 |
|
| 17 | |
| 18 | |
| 19 | enum Entry {
|
| 20 | |
| 21 | |
| 22 | Group(Group, usize),
|
| 23 | Ident(Ident),
|
| 24 | Punct(Punct),
|
| 25 | Literal(Literal),
|
| 26 | |
| 27 | |
| 28 | End(isize, isize),
|
| 29 | }
|
| 30 |
|
| 31 | |
| 32 | |
| 33 | |
| 34 | pub struct TokenBuffer {
|
| 35 | |
| 36 | |
| 37 | entries: Box<[Entry]>,
|
| 38 | }
|
| 39 |
|
| 40 | impl TokenBuffer {
|
| 41 | fn recursive_new(entries: &mut Vec<Entry>, stream: TokenStream) {
|
| 42 | for tt in stream {
|
| 43 | match tt {
|
| 44 | TokenTree::Ident(ident) => entries.push(Entry::Ident(ident)),
|
| 45 | TokenTree::Punct(punct) => entries.push(Entry::Punct(punct)),
|
| 46 | TokenTree::Literal(literal) => entries.push(Entry::Literal(literal)),
|
| 47 | TokenTree::Group(group) => {
|
| 48 | let group_start_index = entries.len();
|
| 49 | entries.push(Entry::End(0, 0)); |
| 50 | Self::recursive_new(entries, group.stream());
|
| 51 | let group_end_index = entries.len();
|
| 52 | let group_offset = group_end_index - group_start_index;
|
| 53 | entries.push(Entry::End(
|
| 54 | -(group_end_index as isize),
|
| 55 | -(group_offset as isize),
|
| 56 | ));
|
| 57 | entries[group_start_index] = Entry::Group(group, group_offset);
|
| 58 | }
|
| 59 | }
|
| 60 | }
|
| 61 | }
|
| 62 |
|
| 63 | |
| 64 | |
| 65 | #[cfg(feature = "proc-macro")]
|
| 66 | #[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))]
|
| 67 | pub fn new(stream: proc_macro::TokenStream) -> Self {
|
| 68 | Self::new2(stream.into())
|
| 69 | }
|
| 70 |
|
| 71 | |
| 72 | |
| 73 | pub fn new2(stream: TokenStream) -> Self {
|
| 74 | let mut entries = Vec::new();
|
| 75 | Self::recursive_new(&mut entries, stream);
|
| 76 | entries.push(Entry::End(-(entries.len() as isize), 0));
|
| 77 | Self {
|
| 78 | entries: entries.into_boxed_slice(),
|
| 79 | }
|
| 80 | }
|
| 81 |
|
| 82 | |
| 83 | |
| 84 | pub fn begin(&self) -> Cursor {
|
| 85 | let ptr = self.entries.as_ptr();
|
| 86 | unsafe { Cursor::create(ptr, ptr.add(self.entries.len() - 1)) }
|
| 87 | }
|
| 88 | }
|
| 89 |
|
| 90 | |
| 91 | |
| 92 | |
| 93 | |
| 94 | |
| 95 | |
| 96 | |
| 97 | |
| 98 | pub struct Cursor<'a> {
|
| 99 | |
| 100 | ptr: *const Entry,
|
| 101 | |
| 102 | |
| 103 | scope: *const Entry,
|
| 104 | |
| 105 | |
| 106 | marker: PhantomData<&'a Entry>,
|
| 107 | }
|
| 108 |
|
| 109 | impl<'a> Cursor<'a> {
|
| 110 | |
| 111 | pub fn empty() -> Self {
|
| 112 | |
| 113 | |
| 114 | |
| 115 | |
| 116 | |
| 117 | |
| 118 | |
| 119 | struct UnsafeSyncEntry(Entry);
|
| 120 | unsafe impl Sync for UnsafeSyncEntry {}
|
| 121 | static EMPTY_ENTRY: UnsafeSyncEntry = UnsafeSyncEntry(Entry::End(0, 0));
|
| 122 |
|
| 123 | Cursor {
|
| 124 | ptr: &EMPTY_ENTRY.0,
|
| 125 | scope: &EMPTY_ENTRY.0,
|
| 126 | marker: PhantomData,
|
| 127 | }
|
| 128 | }
|
| 129 |
|
| 130 | |
| 131 | |
| 132 | |
| 133 | unsafe fn create(mut ptr: *const Entry, scope: *const Entry) -> Self {
|
| 134 | |
| 135 | |
| 136 | |
| 137 | |
| 138 | while let Entry::End(..) = unsafe { &*ptr } {
|
| 139 | if ptr::eq(ptr, scope) {
|
| 140 | break;
|
| 141 | }
|
| 142 | ptr = unsafe { ptr.add(1) };
|
| 143 | }
|
| 144 |
|
| 145 | Cursor {
|
| 146 | ptr,
|
| 147 | scope,
|
| 148 | marker: PhantomData,
|
| 149 | }
|
| 150 | }
|
| 151 |
|
| 152 | |
| 153 | fn entry(self) -> &'a Entry {
|
| 154 | unsafe { &*self.ptr }
|
| 155 | }
|
| 156 |
|
| 157 | |
| 158 | |
| 159 | |
| 160 | |
| 161 | |
| 162 | |
| 163 | unsafe fn bump_ignore_group(self) -> Cursor<'a> {
|
| 164 | unsafe { Cursor::create(self.ptr.offset(1), self.scope) }
|
| 165 | }
|
| 166 |
|
| 167 | |
| 168 | |
| 169 | |
| 170 | |
| 171 | |
| 172 | fn ignore_none(&mut self) {
|
| 173 | while let Entry::Group(group, _) = self.entry() {
|
| 174 | if group.delimiter() == Delimiter::None {
|
| 175 | unsafe { *self = self.bump_ignore_group() };
|
| 176 | } else {
|
| 177 | break;
|
| 178 | }
|
| 179 | }
|
| 180 | }
|
| 181 |
|
| 182 | |
| 183 | |
| 184 | pub fn eof(self) -> bool {
|
| 185 | |
| 186 | ptr::eq(self.ptr, self.scope)
|
| 187 | }
|
| 188 |
|
| 189 | |
| 190 | |
| 191 | pub fn ident(mut self) -> Option<(Ident, Cursor<'a>)> {
|
| 192 | self.ignore_none();
|
| 193 | match self.entry() {
|
| 194 | Entry::Ident(ident) => Some((ident.clone(), unsafe { self.bump_ignore_group() })),
|
| 195 | _ => None,
|
| 196 | }
|
| 197 | }
|
| 198 |
|
| 199 | |
| 200 | |
| 201 | pub fn punct(mut self) -> Option<(Punct, Cursor<'a>)> {
|
| 202 | self.ignore_none();
|
| 203 | match self.entry() {
|
| 204 | Entry::Punct(punct) if punct.as_char() != '\'' => {
|
| 205 | Some((punct.clone(), unsafe { self.bump_ignore_group() }))
|
| 206 | }
|
| 207 | _ => None,
|
| 208 | }
|
| 209 | }
|
| 210 |
|
| 211 | |
| 212 | |
| 213 | pub fn literal(mut self) -> Option<(Literal, Cursor<'a>)> {
|
| 214 | self.ignore_none();
|
| 215 | match self.entry() {
|
| 216 | Entry::Literal(literal) => Some((literal.clone(), unsafe { self.bump_ignore_group() })),
|
| 217 | _ => None,
|
| 218 | }
|
| 219 | }
|
| 220 |
|
| 221 | |
| 222 | |
| 223 | pub fn lifetime(mut self) -> Option<(Lifetime, Cursor<'a>)> {
|
| 224 | self.ignore_none();
|
| 225 | match self.entry() {
|
| 226 | Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => {
|
| 227 | let next = unsafe { self.bump_ignore_group() };
|
| 228 | let (ident, rest) = next.ident()?;
|
| 229 | let lifetime = Lifetime {
|
| 230 | apostrophe: punct.span(),
|
| 231 | ident,
|
| 232 | };
|
| 233 | Some((lifetime, rest))
|
| 234 | }
|
| 235 | _ => None,
|
| 236 | }
|
| 237 | }
|
| 238 |
|
| 239 | |
| 240 | |
| 241 | pub fn group(mut self, delim: Delimiter) -> Option<(Cursor<'a>, DelimSpan, Cursor<'a>)> {
|
| 242 | |
| 243 | |
| 244 | |
| 245 | if delim != Delimiter::None {
|
| 246 | self.ignore_none();
|
| 247 | }
|
| 248 |
|
| 249 | if let Entry::Group(group, end_offset) = self.entry() {
|
| 250 | if group.delimiter() == delim {
|
| 251 | let span = group.delim_span();
|
| 252 | let end_of_group = unsafe { self.ptr.add(*end_offset) };
|
| 253 | let inside_of_group = unsafe { Cursor::create(self.ptr.add(1), end_of_group) };
|
| 254 | let after_group = unsafe { Cursor::create(end_of_group, self.scope) };
|
| 255 | return Some((inside_of_group, span, after_group));
|
| 256 | }
|
| 257 | }
|
| 258 |
|
| 259 | None
|
| 260 | }
|
| 261 |
|
| 262 | |
| 263 | |
| 264 | pub fn any_group(self) -> Option<(Cursor<'a>, Delimiter, DelimSpan, Cursor<'a>)> {
|
| 265 | if let Entry::Group(group, end_offset) = self.entry() {
|
| 266 | let delimiter = group.delimiter();
|
| 267 | let span = group.delim_span();
|
| 268 | let end_of_group = unsafe { self.ptr.add(*end_offset) };
|
| 269 | let inside_of_group = unsafe { Cursor::create(self.ptr.add(1), end_of_group) };
|
| 270 | let after_group = unsafe { Cursor::create(end_of_group, self.scope) };
|
| 271 | return Some((inside_of_group, delimiter, span, after_group));
|
| 272 | }
|
| 273 |
|
| 274 | None
|
| 275 | }
|
| 276 |
|
| 277 | pub(crate) fn any_group_token(self) -> Option<(Group, Cursor<'a>)> {
|
| 278 | if let Entry::Group(group, end_offset) = self.entry() {
|
| 279 | let end_of_group = unsafe { self.ptr.add(*end_offset) };
|
| 280 | let after_group = unsafe { Cursor::create(end_of_group, self.scope) };
|
| 281 | return Some((group.clone(), after_group));
|
| 282 | }
|
| 283 |
|
| 284 | None
|
| 285 | }
|
| 286 |
|
| 287 | |
| 288 | |
| 289 | pub fn token_stream(self) -> TokenStream {
|
| 290 | let mut tts = Vec::new();
|
| 291 | let mut cursor = self;
|
| 292 | while let Some((tt, rest)) = cursor.token_tree() {
|
| 293 | tts.push(tt);
|
| 294 | cursor = rest;
|
| 295 | }
|
| 296 | tts.into_iter().collect()
|
| 297 | }
|
| 298 |
|
| 299 | |
| 300 | |
| 301 | |
| 302 | |
| 303 | |
| 304 | |
| 305 | |
| 306 | pub fn token_tree(self) -> Option<(TokenTree, Cursor<'a>)> {
|
| 307 | let (tree, len) = match self.entry() {
|
| 308 | Entry::Group(group, end_offset) => (group.clone().into(), *end_offset),
|
| 309 | Entry::Literal(literal) => (literal.clone().into(), 1),
|
| 310 | Entry::Ident(ident) => (ident.clone().into(), 1),
|
| 311 | Entry::Punct(punct) => (punct.clone().into(), 1),
|
| 312 | Entry::End(..) => return None,
|
| 313 | };
|
| 314 |
|
| 315 | let rest = unsafe { Cursor::create(self.ptr.add(len), self.scope) };
|
| 316 | Some((tree, rest))
|
| 317 | }
|
| 318 |
|
| 319 | |
| 320 | |
| 321 | pub fn span(mut self) -> Span {
|
| 322 | match self.entry() {
|
| 323 | Entry::Group(group, _) => group.span(),
|
| 324 | Entry::Literal(literal) => literal.span(),
|
| 325 | Entry::Ident(ident) => ident.span(),
|
| 326 | Entry::Punct(punct) => punct.span(),
|
| 327 | Entry::End(_, offset) => {
|
| 328 | self.ptr = unsafe { self.ptr.offset(*offset) };
|
| 329 | if let Entry::Group(group, _) = self.entry() {
|
| 330 | group.span_close()
|
| 331 | } else {
|
| 332 | Span::call_site()
|
| 333 | }
|
| 334 | }
|
| 335 | }
|
| 336 | }
|
| 337 |
|
| 338 | |
| 339 | |
| 340 | #[cfg(any(feature = "full", feature = "derive"))]
|
| 341 | pub(crate) fn prev_span(mut self) -> Span {
|
| 342 | if start_of_buffer(self) < self.ptr {
|
| 343 | self.ptr = unsafe { self.ptr.offset(-1) };
|
| 344 | }
|
| 345 | self.span()
|
| 346 | }
|
| 347 |
|
| 348 | |
| 349 | |
| 350 | |
| 351 | |
| 352 | pub(crate) fn skip(mut self) -> Option<Cursor<'a>> {
|
| 353 | self.ignore_none();
|
| 354 |
|
| 355 | let len = match self.entry() {
|
| 356 | Entry::End(..) => return None,
|
| 357 |
|
| 358 | |
| 359 | Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => {
|
| 360 | match unsafe { &*self.ptr.add(1) } {
|
| 361 | Entry::Ident(_) => 2,
|
| 362 | _ => 1,
|
| 363 | }
|
| 364 | }
|
| 365 |
|
| 366 | Entry::Group(_, end_offset) => *end_offset,
|
| 367 | _ => 1,
|
| 368 | };
|
| 369 |
|
| 370 | Some(unsafe { Cursor::create(self.ptr.add(len), self.scope) })
|
| 371 | }
|
| 372 |
|
| 373 | pub(crate) fn scope_delimiter(self) -> Delimiter {
|
| 374 | match unsafe { &*self.scope } {
|
| 375 | Entry::End(_, offset) => match unsafe { &*self.scope.offset(*offset) } {
|
| 376 | Entry::Group(group, _) => group.delimiter(),
|
| 377 | _ => Delimiter::None,
|
| 378 | },
|
| 379 | _ => unreachable!(),
|
| 380 | }
|
| 381 | }
|
| 382 | }
|
| 383 |
|
| 384 | impl<'a> Copy for Cursor<'a> {}
|
| 385 |
|
| 386 | impl<'a> Clone for Cursor<'a> {
|
| 387 | fn clone(&self) -> Self {
|
| 388 | *self
|
| 389 | }
|
| 390 | }
|
| 391 |
|
| 392 | impl<'a> Eq for Cursor<'a> {}
|
| 393 |
|
| 394 | impl<'a> PartialEq for Cursor<'a> {
|
| 395 | fn eq(&self, other: &Self) -> bool {
|
| 396 | ptr::eq(self.ptr, other.ptr)
|
| 397 | }
|
| 398 | }
|
| 399 |
|
| 400 | impl<'a> PartialOrd for Cursor<'a> {
|
| 401 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
| 402 | if same_buffer(*self, *other) {
|
| 403 | Some(cmp_assuming_same_buffer(*self, *other))
|
| 404 | } else {
|
| 405 | None
|
| 406 | }
|
| 407 | }
|
| 408 | }
|
| 409 |
|
| 410 | pub(crate) fn same_scope(a: Cursor, b: Cursor) -> bool {
|
| 411 | ptr::eq(a.scope, b.scope)
|
| 412 | }
|
| 413 |
|
| 414 | pub(crate) fn same_buffer(a: Cursor, b: Cursor) -> bool {
|
| 415 | ptr::eq(start_of_buffer(a), start_of_buffer(b))
|
| 416 | }
|
| 417 |
|
| 418 | fn start_of_buffer(cursor: Cursor) -> *const Entry {
|
| 419 | unsafe {
|
| 420 | match &*cursor.scope {
|
| 421 | Entry::End(offset, _) => cursor.scope.offset(*offset),
|
| 422 | _ => unreachable!(),
|
| 423 | }
|
| 424 | }
|
| 425 | }
|
| 426 |
|
| 427 | pub(crate) fn cmp_assuming_same_buffer(a: Cursor, b: Cursor) -> Ordering {
|
| 428 | a.ptr.cmp(&b.ptr)
|
| 429 | }
|
| 430 |
|
| 431 | pub(crate) fn open_span_of_group(cursor: Cursor) -> Span {
|
| 432 | match cursor.entry() {
|
| 433 | Entry::Group(group, _) => group.span_open(),
|
| 434 | _ => cursor.span(),
|
| 435 | }
|
| 436 | }
|