diff options
author | Andrei Homescu <ahomescu@google.com> | 2023-10-18 01:21:26 +0000 |
---|---|---|
committer | Andrei Homescu <ahomescu@google.com> | 2023-10-18 01:21:26 +0000 |
commit | b023e3914c3fe9f5431110998717469c90df7bab (patch) | |
tree | 5b2692132d0123514a51e03f263ccd694adc1735 | |
parent | 302de516ded70e59a702aeca94ebc6921a287b47 (diff) | |
parent | 3def4a0b2b2acf4fb092dd4318d17f6674bd8e4c (diff) | |
download | proc-macro2-trusty-main.tar.gz |
Merge remote-tracking branch 'aosp/main' into trusty-maintrusty-main
Change-Id: Id521a9e80a5cef3bf17ba9599e098e0620f7b89e
-rw-r--r-- | BUILD | 59 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | Cargo.toml.orig | 2 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | src/fallback.rs | 61 | ||||
-rw-r--r-- | src/lib.rs | 10 | ||||
-rw-r--r-- | src/parse.rs | 10 | ||||
-rw-r--r-- | tests/test.rs | 18 |
8 files changed, 147 insertions, 17 deletions
@@ -0,0 +1,59 @@ +load("@rules_license//rules:license.bzl", "license") +load("@rules_license//rules:license_kind.bzl", "license_kind") +load("@rules_rust//cargo:defs.bzl", "cargo_build_script") +load("@rules_rust//rust:defs.bzl", "rust_library") + +package( + default_applicable_licenses = [":license"], + default_visibility = ["//visibility:public"], +) + +license( + name = "license", + license_kinds = [ + ":SPDX-license-identifier-Apache-2.0", + ":SPDX-license-identifier-MIT", + ], + license_text = "LICENSE-APACHE", + visibility = [":__subpackages__"], +) + +license_kind( + name = "SPDX-license-identifier-Apache-2.0", + conditions = ["notice"], + url = "https://spdx.org/licenses/Apache-2.0.html", +) + +license_kind( + name = "SPDX-license-identifier-MIT", + conditions = ["notice"], + url = "", +) + +CRATE_FEATURES = [ + "default", + "proc-macro", + "span-locations", +] + +rust_library( + name = "proc-macro2", + srcs = glob(["**/*.rs"]), + crate_features = CRATE_FEATURES, + edition = "2021", + deps = [ + ":proc-macro2_build_script", + # This should map to repo checked out from Android third party project + # "platform/external/rust/crates/unicode-ident". + "@unicode-ident", + ], +) + +cargo_build_script( + name = "proc-macro2_build_script", + srcs = glob(["**/*.rs"]), + crate_features = CRATE_FEATURES, + crate_root = "build.rs", + edition = "2021", + visibility = ["//visibility:private"], +) @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.56" name = "proc-macro2" -version = "1.0.66" +version = "1.0.69" authors = [ "David Tolnay <dtolnay@gmail.com>", "Alex Crichton <alex@alexcrichton.com>", diff --git a/Cargo.toml.orig b/Cargo.toml.orig index b0fb8fd..ca5f7d6 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "proc-macro2" -version = "1.0.66" # remember to update html_root_url +version = "1.0.69" # remember to update html_root_url authors = ["David Tolnay <dtolnay@gmail.com>", "Alex Crichton <alex@alexcrichton.com>"] autobenches = false categories = ["development-tools::procedural-macro-helpers"] @@ -52,7 +52,7 @@ pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { If parsing with [Syn], you'll use [`parse_macro_input!`] instead to propagate parse errors correctly back to the compiler when parsing fails. -[`parse_macro_input!`]: https://docs.rs/syn/1.0/syn/macro.parse_macro_input.html +[`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html ## Unstable features diff --git a/src/fallback.rs b/src/fallback.rs index daa1e17..7f559cf 100644 --- a/src/fallback.rs +++ b/src/fallback.rs @@ -4,6 +4,8 @@ use crate::parse::{self, Cursor}; use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut}; use crate::{Delimiter, Spacing, TokenTree}; #[cfg(all(span_locations, not(fuzzing)))] +use alloc::collections::BTreeMap; +#[cfg(all(span_locations, not(fuzzing)))] use core::cell::RefCell; #[cfg(span_locations)] use core::cmp; @@ -305,7 +307,6 @@ impl SourceFile { } pub fn is_real(&self) -> bool { - // XXX(nika): Support real files in the future? false } } @@ -322,12 +323,13 @@ impl Debug for SourceFile { #[cfg(all(span_locations, not(fuzzing)))] thread_local! { static SOURCE_MAP: RefCell<SourceMap> = RefCell::new(SourceMap { - // NOTE: We start with a single dummy file which all call_site() and - // def_site() spans reference. + // Start with a single dummy file which all call_site() and def_site() + // spans reference. files: vec![FileInfo { source_text: String::new(), span: Span { lo: 0, hi: 0 }, lines: vec![0], + char_index_to_byte_offset: BTreeMap::new(), }], }); } @@ -337,6 +339,7 @@ struct FileInfo { source_text: String, span: Span, lines: Vec<usize>, + char_index_to_byte_offset: BTreeMap<usize, usize>, } #[cfg(all(span_locations, not(fuzzing)))] @@ -363,10 +366,40 @@ impl FileInfo { span.lo >= self.span.lo && span.hi <= self.span.hi } - fn source_text(&self, span: Span) -> String { - let lo = (span.lo - self.span.lo) as usize; - let hi = (span.hi - self.span.lo) as usize; - self.source_text[lo..hi].to_owned() + fn source_text(&mut self, span: Span) -> String { + let lo_char = (span.lo - self.span.lo) as usize; + + // Look up offset of the largest already-computed char index that is + // less than or equal to the current requested one. We resume counting + // chars from that point. + let (&last_char_index, &last_byte_offset) = self + .char_index_to_byte_offset + .range(..=lo_char) + .next_back() + .unwrap_or((&0, &0)); + + let lo_byte = if last_char_index == lo_char { + last_byte_offset + } else { + let total_byte_offset = match self.source_text[last_byte_offset..] + .char_indices() + .nth(lo_char - last_char_index) + { + Some((additional_offset, _ch)) => last_byte_offset + additional_offset, + None => self.source_text.len(), + }; + self.char_index_to_byte_offset + .insert(lo_char, total_byte_offset); + total_byte_offset + }; + + let trunc_lo = &self.source_text[lo_byte..]; + let char_len = (span.hi - span.lo) as usize; + let source_text = match trunc_lo.char_indices().nth(char_len) { + Some((offset, _ch)) => &trunc_lo[..offset], + None => trunc_lo, + }; + source_text.to_owned() } } @@ -405,7 +438,6 @@ impl SourceMap { fn add_file(&mut self, src: &str) -> Span { let (len, lines) = lines_offsets(src); let lo = self.next_start_pos(); - // XXX(nika): Should we bother doing a checked cast or checked add here? let span = Span { lo, hi: lo + (len as u32), @@ -415,6 +447,8 @@ impl SourceMap { source_text: src.to_owned(), span, lines, + // Populated lazily by source_text(). + char_index_to_byte_offset: BTreeMap::new(), }); span @@ -442,6 +476,15 @@ impl SourceMap { } unreachable!("Invalid span with no related FileInfo!"); } + + fn fileinfo_mut(&mut self, span: Span) -> &mut FileInfo { + for file in &mut self.files { + if file.span_within(span) { + return file; + } + } + unreachable!("Invalid span with no related FileInfo!"); + } } #[derive(Clone, Copy, PartialEq, Eq)] @@ -566,7 +609,7 @@ impl Span { if self.is_call_site() { None } else { - Some(SOURCE_MAP.with(|cm| cm.borrow().fileinfo(*self).source_text(*self))) + Some(SOURCE_MAP.with(|cm| cm.borrow_mut().fileinfo_mut(*self).source_text(*self))) } } } @@ -55,7 +55,7 @@ //! If parsing with [Syn], you'll use [`parse_macro_input!`] instead to //! propagate parse errors correctly back to the compiler when parsing fails. //! -//! [`parse_macro_input!`]: https://docs.rs/syn/1.0/syn/macro.parse_macro_input.html +//! [`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html //! //! # Unstable features //! @@ -86,7 +86,7 @@ //! a different thread. // Proc-macro2 types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.66")] +#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.69")] #![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] #![cfg_attr(super_unstable, feature(proc_macro_def_site))] #![cfg_attr(doc_cfg, feature(doc_cfg))] @@ -95,9 +95,11 @@ clippy::cast_possible_truncation, clippy::doc_markdown, clippy::items_after_statements, + clippy::iter_without_into_iter, clippy::let_underscore_untyped, clippy::manual_assert, clippy::manual_range_contains, + clippy::missing_safety_doc, clippy::must_use_candidate, clippy::needless_doctest_main, clippy::new_without_default, @@ -852,7 +854,7 @@ impl Debug for Punct { /// Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the /// behaviour of `Ident::new`. /// -/// [`Parse`]: https://docs.rs/syn/1.0/syn/parse/trait.Parse.html +/// [`Parse`]: https://docs.rs/syn/2.0/syn/parse/trait.Parse.html /// /// # Examples /// @@ -943,7 +945,7 @@ impl Ident { /// Panics if the input string is neither a keyword nor a legal variable /// name. If you are not sure whether the string contains an identifier and /// need to handle an error case, use - /// <a href="https://docs.rs/syn/1.0/syn/fn.parse_str.html"><code + /// <a href="https://docs.rs/syn/2.0/syn/fn.parse_str.html"><code /// style="padding-right:0;">syn::parse_str</code></a><code /// style="padding-left:0;">::<Ident></code> /// rather than `Ident::new`. diff --git a/src/parse.rs b/src/parse.rs index c084e4c..1430d73 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -161,6 +161,10 @@ fn word_break(input: Cursor) -> Result<Cursor, Reject> { } } +// Rustc's representation of a macro expansion error in expression position or +// type position. +const ERROR: &str = "(/*ERROR*/)"; + pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> { let mut trees = TokenStreamBuilder::new(); let mut stack = Vec::new(); @@ -192,7 +196,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> { }; if let Some(open_delimiter) = match first { - b'(' => Some(Delimiter::Parenthesis), + b'(' if !input.starts_with(ERROR) => Some(Delimiter::Parenthesis), b'[' => Some(Delimiter::Bracket), b'{' => Some(Delimiter::Brace), _ => None, @@ -267,6 +271,10 @@ fn leaf_token(input: Cursor) -> PResult<TokenTree> { Ok((input, TokenTree::Punct(p))) } else if let Ok((input, i)) = ident(input) { Ok((input, TokenTree::Ident(i))) + } else if input.starts_with(ERROR) { + let rest = input.advance(ERROR.len()); + let repr = crate::Literal::_new_fallback(Literal::_new(ERROR.to_owned())); + Ok((rest, TokenTree::Literal(repr))) } else { Err(Reject) } diff --git a/tests/test.rs b/tests/test.rs index 8e47b46..b75cd55 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -325,6 +325,24 @@ fn literal_span() { assert!(positive.subspan(1..4).is_none()); } +#[cfg(span_locations)] +#[test] +fn source_text() { + let input = " 𓀕 a z "; + let mut tokens = input + .parse::<proc_macro2::TokenStream>() + .unwrap() + .into_iter(); + + let first = tokens.next().unwrap(); + assert_eq!("𓀕", first.span().source_text().unwrap()); + + let second = tokens.next().unwrap(); + let third = tokens.next().unwrap(); + assert_eq!("z", third.span().source_text().unwrap()); + assert_eq!("a", second.span().source_text().unwrap()); +} + #[test] fn roundtrip() { fn roundtrip(p: &str) { |