summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-prod (mdb) <android-build-team-robot@google.com>2020-05-27 20:49:07 +0000
committerandroid-build-prod (mdb) <android-build-team-robot@google.com>2020-05-27 20:49:07 +0000
commit8eedea5db67e2a462825e431cacc2baa0613333e (patch)
treea33f77d49a0ca4530c7d4ddd15c1d87520e647c7
parent55118ea7a7ada999e0b8a25c9efe6c926ca91718 (diff)
parentdfc35a2c85654d53298514ffc85469e7024a082a (diff)
downloadpaste-impl-8eedea5db67e2a462825e431cacc2baa0613333e.tar.gz
Snap for 6533464 from dfc35a2c85654d53298514ffc85469e7024a082a to sdk-releaseplatform-tools-30.0.3platform-tools-30.0.2
Change-Id: I76f507336f58158c70f3629fcd705bcc0da2a15f
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Cargo.toml4
-rw-r--r--Cargo.toml.orig5
-rw-r--r--METADATA6
-rw-r--r--src/lib.rs109
5 files changed, 91 insertions, 35 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 28d7b30..1347e27 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
{
"git": {
- "sha1": "5feb37605c9ec2d237651dbd669e3527566a839e"
+ "sha1": "157559c3faf524ae24f8329537d2a763f6e18931"
}
}
diff --git a/Cargo.toml b/Cargo.toml
index 90aff3f..97a4cab 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "paste-impl"
-version = "0.1.10"
+version = "0.1.14"
authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "Implementation detail of the `paste` crate"
license = "MIT OR Apache-2.0"
@@ -34,5 +34,3 @@ version = "1.0"
[dependencies.syn]
version = "1.0"
-[badges.travis-ci]
-repository = "dtolnay/paste"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 9b7a04e..80d2071 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "paste-impl"
-version = "0.1.10"
+version = "0.1.14"
authors = ["David Tolnay <dtolnay@gmail.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
@@ -10,9 +10,6 @@ repository = "https://github.com/dtolnay/paste"
[lib]
proc-macro = true
-[badges]
-travis-ci = { repository = "dtolnay/paste" }
-
[dependencies]
proc-macro-hack = "0.5"
proc-macro2 = "1.0"
diff --git a/METADATA b/METADATA
index e289934..2b0d5de 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@ third_party {
type: GIT
value: "https://github.com/dtolnay/paste"
}
- version: "0.1.10"
+ version: "0.1.14"
license_type: NOTICE
last_upgrade_date {
year: 2020
- month: 4
- day: 17
+ month: 5
+ day: 25
}
}
diff --git a/src/lib.rs b/src/lib.rs
index b2c1e41..1c762d9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -40,31 +40,57 @@ struct PasteInput {
impl Parse for PasteInput {
fn parse(input: ParseStream) -> Result<Self> {
- let mut expanded = TokenStream::new();
- while !input.is_empty() {
- match input.parse()? {
- TokenTree::Group(group) => {
- let delimiter = group.delimiter();
- let content = group.stream();
- let span = group.span();
- if delimiter == Delimiter::Bracket && is_paste_operation(&content) {
- let segments = parse_bracket_as_segments.parse2(content)?;
- let pasted = paste_segments(span, &segments)?;
- pasted.to_tokens(&mut expanded);
- } else if delimiter == Delimiter::None && is_single_ident(&content) {
- content.to_tokens(&mut expanded);
- } else {
- let nested = PasteInput::parse.parse2(content)?;
- let mut group = Group::new(delimiter, nested.expanded);
+ let mut contains_paste = false;
+ let expanded = parse(input, &mut contains_paste)?;
+ Ok(PasteInput { expanded })
+ }
+}
+
+fn parse(input: ParseStream, contains_paste: &mut bool) -> Result<TokenStream> {
+ let mut expanded = TokenStream::new();
+ let (mut prev_colons, mut colons) = (false, false);
+ while !input.is_empty() {
+ let save = input.fork();
+ match input.parse()? {
+ TokenTree::Group(group) => {
+ let delimiter = group.delimiter();
+ let content = group.stream();
+ let span = group.span();
+ let in_path = prev_colons || input.peek(Token![::]);
+ if delimiter == Delimiter::Bracket && is_paste_operation(&content) {
+ let segments = parse_bracket_as_segments.parse2(content)?;
+ let pasted = paste_segments(span, &segments)?;
+ pasted.to_tokens(&mut expanded);
+ *contains_paste = true;
+ } else if is_none_delimited_single_ident_or_lifetime(delimiter, &content) {
+ content.to_tokens(&mut expanded);
+ *contains_paste |= in_path;
+ } else {
+ let mut group_contains_paste = false;
+ let nested = (|input: ParseStream| parse(input, &mut group_contains_paste))
+ .parse2(content)?;
+ let group = if group_contains_paste {
+ let mut group = Group::new(delimiter, nested);
group.set_span(span);
+ *contains_paste = true;
+ group
+ } else {
+ group.clone()
+ };
+ if in_path && delimiter == Delimiter::None {
+ group.stream().to_tokens(&mut expanded);
+ *contains_paste = true;
+ } else {
group.to_tokens(&mut expanded);
}
}
- other => other.to_tokens(&mut expanded),
}
+ other => other.to_tokens(&mut expanded),
}
- Ok(PasteInput { expanded })
+ prev_colons = colons;
+ colons = save.peek(Token![::]);
}
+ Ok(expanded)
}
fn is_paste_operation(input: &TokenStream) -> bool {
@@ -72,15 +98,30 @@ fn is_paste_operation(input: &TokenStream) -> bool {
parse_bracket_as_segments.parse2(input).is_ok()
}
-fn is_single_ident(input: &TokenStream) -> bool {
- let mut has_ident = false;
+// https://github.com/dtolnay/paste/issues/26
+fn is_none_delimited_single_ident_or_lifetime(delimiter: Delimiter, input: &TokenStream) -> bool {
+ if delimiter != Delimiter::None {
+ return false;
+ }
+
+ #[derive(PartialEq)]
+ enum State {
+ Init,
+ Ident,
+ Apostrophe,
+ Lifetime,
+ }
+
+ let mut state = State::Init;
for tt in input.clone() {
- match tt {
- TokenTree::Ident(_) if !has_ident => has_ident = true,
+ state = match (state, &tt) {
+ (State::Init, TokenTree::Ident(_)) => State::Ident,
+ (State::Init, TokenTree::Punct(punct)) if punct.as_char() == '\'' => State::Apostrophe,
+ (State::Apostrophe, TokenTree::Ident(_)) => State::Lifetime,
_ => return false,
- }
+ };
}
- has_ident
+ state == State::Ident || state == State::Lifetime
}
enum Segment {
@@ -194,6 +235,26 @@ fn paste_segments(span: Span, segments: &[Segment]) -> Result<TokenStream> {
prev = ch;
}
evaluated.push(acc.to_lowercase());
+ } else if ident == "camel" {
+ let mut acc = String::new();
+ let mut prev = '_';
+ for ch in last.chars() {
+ if ch != '_' {
+ if prev == '_' {
+ for chu in ch.to_uppercase() {
+ acc.push(chu);
+ }
+ } else if prev.is_uppercase() {
+ for chl in ch.to_lowercase() {
+ acc.push(chl);
+ }
+ } else {
+ acc.push(ch);
+ }
+ }
+ prev = ch;
+ }
+ evaluated.push(acc);
} else {
return Err(Error::new_spanned(span, "unsupported modifier"));
}