use crate::ast;
use crate::ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment};
use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem};
-use crate::ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam};
+use crate::ast::{Lit, LitKind, Expr, Item, Local, Stmt, StmtKind, GenericParam};
use crate::mut_visit::visit_clobber;
use crate::source_map::{BytePos, Spanned, dummy_spanned};
use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use crate::parse::{self, ParseSess, PResult};
use crate::parse::token::{self, Token};
use crate::ptr::P;
-use crate::symbol::{keywords, LocalInternedString, Symbol};
+use crate::symbol::{keywords, Symbol};
use crate::ThinVec;
use crate::tokenstream::{TokenStream, TokenTree, DelimSpan};
use crate::GLOBALS;
}
/// Returns `true` if this list item is a MetaItem with a name of `name`.
- pub fn check_name<T>(&self, name: T) -> bool
- where
- Path: PartialEq<T>,
- {
+ pub fn check_name(&self, name: Symbol) -> bool {
self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
}
pub fn ident(&self) -> Option<Ident> {
self.meta_item().and_then(|meta_item| meta_item.ident())
}
- pub fn name_or_empty(&self) -> LocalInternedString {
- self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str()
+ pub fn name_or_empty(&self) -> Symbol {
+ self.ident().unwrap_or(keywords::Invalid.ident()).name
}
/// Gets the string value if self is a MetaItem and the MetaItem is a
/// attribute is marked as used.
///
/// To check the attribute name without marking it used, use the `path` field directly.
- pub fn check_name<T>(&self, name: T) -> bool
- where
- Path: PartialEq<T>,
- {
+ pub fn check_name(&self, name: Symbol) -> bool {
let matches = self.path == name;
if matches {
mark_used(self);
None
}
}
- pub fn name_or_empty(&self) -> LocalInternedString {
- self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str()
+ pub fn name_or_empty(&self) -> Symbol {
+ self.ident().unwrap_or(keywords::Invalid.ident()).name
}
pub fn value_str(&self) -> Option<Symbol> {
None
}
}
- pub fn name_or_empty(&self) -> LocalInternedString {
- self.ident().unwrap_or(keywords::Invalid.ident()).name.as_str()
+ pub fn name_or_empty(&self) -> Symbol {
+ self.ident().unwrap_or(keywords::Invalid.ident()).name
}
// #[attribute(name = "value")]
}
}
- pub fn check_name<T>(&self, name: T) -> bool
- where
- Path: PartialEq<T>,
- {
+ pub fn check_name(&self, name: Symbol) -> bool {
self.path == name
}
/* Constructors */
pub fn mk_name_value_item_str(ident: Ident, value: Spanned<Symbol>) -> MetaItem {
- let node = LitKind::Str(value.node, ast::StrStyle::Cooked);
- let (token, suffix) = node.lit_token();
- let value = Lit { node, token, suffix, span: value.span };
- mk_name_value_item(ident.span.to(value.span), ident, value)
+ let lit_kind = LitKind::Str(value.node, ast::StrStyle::Cooked);
+ mk_name_value_item(ident.span.to(value.span), ident, lit_kind, value.span)
}
-pub fn mk_name_value_item(span: Span, ident: Ident, value: Lit) -> MetaItem {
- MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) }
+pub fn mk_name_value_item(span: Span, ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem {
+ let lit = Lit::from_lit_kind(lit_kind, lit_span);
+ MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(lit) }
}
pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute {
let style = doc_comment_style(&text.as_str());
- let node = LitKind::Str(text, ast::StrStyle::Cooked);
- let (token, suffix) = node.lit_token();
- let lit = Lit { node, token, suffix, span };
+ let lit_kind = LitKind::Str(text, ast::StrStyle::Cooked);
+ let lit = Lit::from_lit_kind(lit_kind, span);
Attribute {
id,
style,
}
}
-pub fn list_contains_name(items: &[NestedMetaItem], name: &str) -> bool {
+pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool {
items.iter().any(|item| {
item.check_name(name)
})
}
-pub fn contains_name(attrs: &[Attribute], name: &str) -> bool {
+pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool {
attrs.iter().any(|item| {
item.check_name(name)
})
}
-pub fn find_by_name<'a>(attrs: &'a [Attribute], name: &str) -> Option<&'a Attribute> {
+pub fn find_by_name<'a>(attrs: &'a [Attribute], name: Symbol) -> Option<&'a Attribute> {
attrs.iter().find(|attr| attr.check_name(name))
}
-pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: &'a str)
+pub fn filter_by_name<'a>(attrs: &'a [Attribute], name: Symbol)
-> impl Iterator<Item = &'a Attribute> {
attrs.iter().filter(move |attr| attr.check_name(name))
}
-pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option<Symbol> {
+pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: Symbol) -> Option<Symbol> {
attrs.iter()
.find(|at| at.check_name(name))
.and_then(|at| at.value_str())
Some(TokenTree::Token(_, token::Eq)) => {
tokens.next();
return if let Some(TokenTree::Token(span, token)) = tokens.next() {
- LitKind::from_token(token)
- .map(|(node, token, suffix)| MetaItemKind::NameValue(Lit { node, token, suffix, span }))
+ Lit::from_token(&token, span, None).map(MetaItemKind::NameValue)
} else {
None
};
where I: Iterator<Item = TokenTree>,
{
if let Some(TokenTree::Token(span, token)) = tokens.peek().cloned() {
- if let Some((node, token, suffix)) = LitKind::from_token(token) {
+ if let Some(lit) = Lit::from_token(&token, span, None) {
tokens.next();
- return Some(NestedMetaItem::Literal(Lit { node, token, suffix, span }));
+ return Some(NestedMetaItem::Literal(lit));
}
}
}
}
-impl Lit {
- crate fn tokens(&self) -> TokenStream {
- TokenTree::Token(self.span, self.node.token()).into()
- }
-}
-
-impl LitKind {
- fn token(&self) -> Token {
- match self.lit_token() {
- (token::Bool(symbol), _) => Token::Ident(Ident::with_empty_ctxt(symbol), false),
- (lit, suffix) => Token::Literal(lit, suffix),
- }
- }
-
- pub(crate) fn lit_token(&self) -> (token::Lit, Option<Symbol>) {
- use std::ascii;
-
- match *self {
- LitKind::Str(string, ast::StrStyle::Cooked) => {
- let escaped = string.as_str().escape_default().to_string();
- (token::Lit::Str_(Symbol::intern(&escaped)), None)
- }
- LitKind::Str(string, ast::StrStyle::Raw(n)) => {
- (token::Lit::StrRaw(string, n), None)
- }
- LitKind::ByteStr(ref bytes) => {
- let string = bytes.iter().cloned().flat_map(ascii::escape_default)
- .map(Into::<char>::into).collect::<String>();
- (token::Lit::ByteStr(Symbol::intern(&string)), None)
- }
- LitKind::Byte(byte) => {
- let string: String = ascii::escape_default(byte).map(Into::<char>::into).collect();
- (token::Lit::Byte(Symbol::intern(&string)), None)
- }
- LitKind::Char(ch) => {
- let string: String = ch.escape_default().map(Into::<char>::into).collect();
- (token::Lit::Char(Symbol::intern(&string)), None)
- }
- LitKind::Int(n, ty) => {
- let suffix = match ty {
- ast::LitIntType::Unsigned(ty) => Some(Symbol::intern(ty.ty_to_string())),
- ast::LitIntType::Signed(ty) => Some(Symbol::intern(ty.ty_to_string())),
- ast::LitIntType::Unsuffixed => None,
- };
- (token::Lit::Integer(Symbol::intern(&n.to_string())), suffix)
- }
- LitKind::Float(symbol, ty) => {
- (token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string())))
- }
- LitKind::FloatUnsuffixed(symbol) => (token::Lit::Float(symbol), None),
- LitKind::Bool(value) => {
- let kw = if value { keywords::True } else { keywords::False };
- (token::Lit::Bool(kw.name()), None)
- }
- LitKind::Err(val) => (token::Lit::Err(val), None),
- }
- }
-
- fn from_token(token: Token) -> Option<(LitKind, token::Lit, Option<Symbol>)> {
- match token {
- Token::Ident(ident, false) if ident.name == keywords::True.name() =>
- Some((LitKind::Bool(true), token::Bool(ident.name), None)),
- Token::Ident(ident, false) if ident.name == keywords::False.name() =>
- Some((LitKind::Bool(false), token::Bool(ident.name), None)),
- Token::Interpolated(nt) => match *nt {
- token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node {
- ExprKind::Lit(ref lit) => Some((lit.node.clone(), lit.token, lit.suffix)),
- _ => None,
- },
- _ => None,
- },
- Token::Literal(lit, suf) => {
- let (suffix_illegal, result) = parse::lit_token(lit, suf, None);
- if result.is_none() || suffix_illegal && suf.is_some() {
- return None;
- }
- Some((result.unwrap(), lit, suf))
- }
- _ => None,
- }
- }
-}
-
pub trait HasAttrs: Sized {
fn attrs(&self) -> &[ast::Attribute];
fn visit_attrs<F: FnOnce(&mut Vec<ast::Attribute>)>(&mut self, f: F);