impl FromStr for proc_macro::Literal
This commit is contained in:
parent
965bce4834
commit
34585cb678
@ -1,9 +1,7 @@
|
||||
use crate::base::{ExtCtxt, ResolverExpand};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::token;
|
||||
use rustc_ast::token::Nonterminal;
|
||||
use rustc_ast::token::NtIdent;
|
||||
use rustc_ast::token::{self, Nonterminal, NtIdent, TokenKind};
|
||||
use rustc_ast::tokenstream::{self, CanSynthesizeMissingTokens};
|
||||
use rustc_ast::tokenstream::{DelimSpan, Spacing::*, TokenStream, TreeAndSpacing};
|
||||
use rustc_ast_pretty::pprust;
|
||||
@ -541,6 +539,33 @@ impl server::Ident for Rustc<'_> {
|
||||
}
|
||||
|
||||
impl server::Literal for Rustc<'_> {
|
||||
fn from_str(&mut self, s: &str) -> Result<Self::Literal, ()> {
|
||||
let override_span = None;
|
||||
let stream = parse_stream_from_source_str(
|
||||
FileName::proc_macro_source_code(s),
|
||||
s.to_owned(),
|
||||
self.sess,
|
||||
override_span,
|
||||
);
|
||||
if stream.len() != 1 {
|
||||
return Err(());
|
||||
}
|
||||
let tree = stream.into_trees().next().unwrap();
|
||||
let token = match tree {
|
||||
tokenstream::TokenTree::Token(token) => token,
|
||||
tokenstream::TokenTree::Delimited { .. } => return Err(()),
|
||||
};
|
||||
let span_data = token.span.data();
|
||||
if (span_data.hi.0 - span_data.lo.0) as usize != s.len() {
|
||||
// There is a comment or whitespace adjacent to the literal.
|
||||
return Err(());
|
||||
}
|
||||
let lit = match token.kind {
|
||||
TokenKind::Literal(lit) => lit,
|
||||
_ => return Err(()),
|
||||
};
|
||||
Ok(Literal { lit, span: self.call_site })
|
||||
}
|
||||
fn debug_kind(&mut self, literal: &Self::Literal) -> String {
|
||||
format!("{:?}", literal.lit.kind)
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ macro_rules! with_api {
|
||||
Literal {
|
||||
fn drop($self: $S::Literal);
|
||||
fn clone($self: &$S::Literal) -> $S::Literal;
|
||||
fn from_str(s: &str) -> Result<$S::Literal, ()>;
|
||||
fn debug_kind($self: &$S::Literal) -> String;
|
||||
fn symbol($self: &$S::Literal) -> String;
|
||||
fn suffix($self: &$S::Literal) -> Option<String>;
|
||||
@ -315,6 +316,19 @@ impl<T: Unmark> Unmark for Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Mark, E: Mark> Mark for Result<T, E> {
|
||||
type Unmarked = Result<T::Unmarked, E::Unmarked>;
|
||||
fn mark(unmarked: Self::Unmarked) -> Self {
|
||||
unmarked.map(T::mark).map_err(E::mark)
|
||||
}
|
||||
}
|
||||
impl<T: Unmark, E: Unmark> Unmark for Result<T, E> {
|
||||
type Unmarked = Result<T::Unmarked, E::Unmarked>;
|
||||
fn unmark(self) -> Self::Unmarked {
|
||||
self.map(T::unmark).map_err(E::unmark)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! mark_noop {
|
||||
($($ty:ty),* $(,)?) => {
|
||||
$(
|
||||
|
@ -91,6 +91,12 @@ pub struct LexError {
|
||||
_inner: (),
|
||||
}
|
||||
|
||||
impl LexError {
|
||||
fn new() -> Self {
|
||||
LexError { _inner: () }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")]
|
||||
impl fmt::Display for LexError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
@ -1171,6 +1177,28 @@ impl Literal {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a single literal from its stringified representation.
|
||||
///
|
||||
/// In order to parse successfully, the input string must not contain anything
|
||||
/// but the literal token. Specifically, it must not contain whitespace or
|
||||
/// comments in addition to the literal.
|
||||
///
|
||||
/// The resulting literal token will have a `Span::call_site()` span.
|
||||
///
|
||||
/// NOTE: some errors may cause panics instead of returning `LexError`. We
|
||||
/// reserve the right to change these errors into `LexError`s later.
|
||||
#[stable(feature = "proc_macro_literal_parse", since = "1.54.0")]
|
||||
impl FromStr for Literal {
|
||||
type Err = LexError;
|
||||
|
||||
fn from_str(src: &str) -> Result<Self, LexError> {
|
||||
match bridge::client::Literal::from_str(src) {
|
||||
Ok(literal) => Ok(Literal(literal)),
|
||||
Err(()) => Err(LexError::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// N.B., the bridge only provides `to_string`, implement `fmt::Display`
|
||||
// based on it (the reverse of the usual relationship between the two).
|
||||
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
|
||||
|
Loading…
x
Reference in New Issue
Block a user