Turn some functions from token.rs into methods on Ident

This commit is contained in:
Vadim Petrochenkov 2018-05-13 16:14:43 +03:00
parent f4cbc2388f
commit c4352ff198
10 changed files with 80 additions and 67 deletions

View file

@ -13,7 +13,7 @@ pub use self::AnnNode::*;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use syntax::ast; use syntax::ast;
use syntax::codemap::{CodeMap, Spanned}; use syntax::codemap::{CodeMap, Spanned};
use syntax::parse::{token, ParseSess}; use syntax::parse::ParseSess;
use syntax::parse::lexer::comments; use syntax::parse::lexer::comments;
use syntax::print::pp::{self, Breaks}; use syntax::print::pp::{self, Breaks};
use syntax::print::pp::Breaks::{Consistent, Inconsistent}; use syntax::print::pp::Breaks::{Consistent, Inconsistent};
@ -1559,7 +1559,7 @@ impl<'a> State<'a> {
} }
pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> { pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
if token::is_raw_guess(ast::Ident::with_empty_ctxt(name)) { if name.to_ident().is_raw_guess() {
self.s.word(&format!("r#{}", name))?; self.s.word(&format!("r#{}", name))?;
} else { } else {
self.s.word(&name.as_str())?; self.s.word(&name.as_str())?;

View file

@ -21,7 +21,6 @@ use rustc::session::Session;
use syntax::ast::*; use syntax::ast::*;
use syntax::attr; use syntax::attr;
use syntax::codemap::Spanned; use syntax::codemap::Spanned;
use syntax::parse::token;
use syntax::symbol::keywords; use syntax::symbol::keywords;
use syntax::visit::{self, Visitor}; use syntax::visit::{self, Visitor};
use syntax_pos::Span; use syntax_pos::Span;
@ -40,14 +39,13 @@ impl<'a> AstValidator<'a> {
let valid_names = [keywords::UnderscoreLifetime.name(), let valid_names = [keywords::UnderscoreLifetime.name(),
keywords::StaticLifetime.name(), keywords::StaticLifetime.name(),
keywords::Invalid.name()]; keywords::Invalid.name()];
if !valid_names.contains(&ident.name) && if !valid_names.contains(&ident.name) && ident.without_first_quote().is_reserved() {
token::is_reserved_ident(ident.without_first_quote()) {
self.err_handler().span_err(ident.span, "lifetimes cannot use keyword names"); self.err_handler().span_err(ident.span, "lifetimes cannot use keyword names");
} }
} }
fn check_label(&self, ident: Ident) { fn check_label(&self, ident: Ident) {
if token::is_reserved_ident(ident.without_first_quote()) { if ident.without_first_quote().is_reserved() {
self.err_handler() self.err_handler()
.span_err(ident.span, &format!("invalid label name `{}`", ident.name)); .span_err(ident.span, &format!("invalid label name `{}`", ident.name));
} }

View file

@ -58,7 +58,6 @@ use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path}; use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path};
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind}; use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
use syntax::feature_gate::{feature_err, GateIssue}; use syntax::feature_gate::{feature_err, GateIssue};
use syntax::parse::token;
use syntax::ptr::P; use syntax::ptr::P;
use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use syntax_pos::{Span, DUMMY_SP, MultiSpan};
@ -3274,7 +3273,7 @@ impl<'a> Resolver<'a> {
// `$crate::a::b` // `$crate::a::b`
module = Some(self.resolve_crate_root(ident.span.ctxt(), true)); module = Some(self.resolve_crate_root(ident.span.ctxt(), true));
continue continue
} else if i == 1 && !token::is_path_segment_keyword(ident) { } else if i == 1 && !ident.is_path_segment_keyword() {
let prev_name = path[0].name; let prev_name = path[0].name;
if prev_name == keywords::Extern.name() || if prev_name == keywords::Extern.name() ||
prev_name == keywords::CrateRoot.name() && prev_name == keywords::CrateRoot.name() &&

View file

@ -27,7 +27,6 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet};
use syntax::ast::{Ident, Name, NodeId}; use syntax::ast::{Ident, Name, NodeId};
use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
use syntax::ext::hygiene::Mark; use syntax::ext::hygiene::Mark;
use syntax::parse::token;
use syntax::symbol::keywords; use syntax::symbol::keywords;
use syntax::util::lev_distance::find_best_match_for_name; use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::Span; use syntax_pos::Span;
@ -667,7 +666,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
} else { } else {
Some(self.resolve_crate_root(source.span.ctxt().modern(), false)) Some(self.resolve_crate_root(source.span.ctxt().modern(), false))
} }
} else if is_extern && !token::is_path_segment_keyword(source) { } else if is_extern && !source.is_path_segment_keyword() {
let crate_id = let crate_id =
self.resolver.crate_loader.process_use_extern( self.resolver.crate_loader.process_use_extern(
source.name, source.name,
@ -715,7 +714,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
} }
PathResult::Failed(span, msg, true) => { PathResult::Failed(span, msg, true) => {
let (mut self_path, mut self_result) = (module_path.clone(), None); let (mut self_path, mut self_result) = (module_path.clone(), None);
let is_special = |ident| token::is_path_segment_keyword(ident) && let is_special = |ident: Ident| ident.is_path_segment_keyword() &&
ident.name != keywords::CrateRoot.name(); ident.name != keywords::CrateRoot.name();
if !self_path.is_empty() && !is_special(self_path[0]) && if !self_path.is_empty() && !is_special(self_path[0]) &&
!(self_path.len() > 1 && is_special(self_path[1])) { !(self_path.len() > 1 && is_special(self_path[1])) {

View file

@ -107,8 +107,7 @@ impl Path {
// or starts with something like `self`/`super`/`$crate`/etc. // or starts with something like `self`/`super`/`$crate`/etc.
pub fn make_root(&self) -> Option<PathSegment> { pub fn make_root(&self) -> Option<PathSegment> {
if let Some(ident) = self.segments.get(0).map(|seg| seg.ident) { if let Some(ident) = self.segments.get(0).map(|seg| seg.ident) {
if ::parse::token::is_path_segment_keyword(ident) && if ident.is_path_segment_keyword() && ident.name != keywords::Crate.name() {
ident.name != keywords::Crate.name() {
return None; return None;
} }
} }

View file

@ -1149,7 +1149,7 @@ impl<'a> StringReader<'a> {
return Ok(self.with_str_from(start, |string| { return Ok(self.with_str_from(start, |string| {
// FIXME: perform NFKC normalization here. (Issue #2253) // FIXME: perform NFKC normalization here. (Issue #2253)
let ident = self.mk_ident(string); let ident = self.mk_ident(string);
if is_raw_ident && (token::is_path_segment_keyword(ident) || if is_raw_ident && (ident.is_path_segment_keyword() ||
ident.name == keywords::Underscore.name()) { ident.name == keywords::Underscore.name()) {
self.fatal_span_(raw_start, self.pos, self.fatal_span_(raw_start, self.pos,
&format!("`r#{}` is not currently supported.", ident.name) &format!("`r#{}` is not currently supported.", ident.name)

View file

@ -15,14 +15,13 @@ pub use self::Lit::*;
pub use self::Token::*; pub use self::Token::*;
use ast::{self}; use ast::{self};
use edition::Edition;
use parse::ParseSess; use parse::ParseSess;
use print::pprust; use print::pprust;
use ptr::P; use ptr::P;
use serialize::{Decodable, Decoder, Encodable, Encoder}; use serialize::{Decodable, Decoder, Encodable, Encoder};
use symbol::keywords; use symbol::keywords;
use syntax::parse::parse_stream_from_source_str; use syntax::parse::parse_stream_from_source_str;
use syntax_pos::{self, hygiene, Span, FileName}; use syntax_pos::{self, Span, FileName};
use tokenstream::{TokenStream, TokenTree}; use tokenstream::{TokenStream, TokenTree};
use tokenstream; use tokenstream;
@ -139,48 +138,6 @@ fn ident_can_begin_type(ident: ast::Ident, is_raw: bool) -> bool {
].contains(&ident.name) ].contains(&ident.name)
} }
pub fn is_path_segment_keyword(id: ast::Ident) -> bool {
id.name == keywords::Super.name() ||
id.name == keywords::SelfValue.name() ||
id.name == keywords::SelfType.name() ||
id.name == keywords::Extern.name() ||
id.name == keywords::Crate.name() ||
id.name == keywords::CrateRoot.name() ||
id.name == keywords::DollarCrate.name()
}
// We see this identifier in a normal identifier position, like variable name or a type.
// How was it written originally? Did it use the raw form? Let's try to guess.
pub fn is_raw_guess(ident: ast::Ident) -> bool {
ident.name != keywords::Invalid.name() &&
is_reserved_ident(ident) && !is_path_segment_keyword(ident)
}
// Returns true for reserved identifiers used internally for elided lifetimes,
// unnamed method parameters, crate root module, error recovery etc.
pub fn is_special_ident(id: ast::Ident) -> bool {
id.name <= keywords::Underscore.name()
}
/// Returns `true` if the token is a keyword used in the language.
pub fn is_used_keyword(id: ast::Ident) -> bool {
id.name >= keywords::As.name() && id.name <= keywords::While.name()
}
/// Returns `true` if the token is a keyword reserved for possible future use.
pub fn is_unused_keyword(id: ast::Ident) -> bool {
let edition = || id.span.ctxt().outer().expn_info().map_or_else(|| hygiene::default_edition(),
|einfo| einfo.callee.edition);
id.name >= keywords::Abstract.name() && id.name <= keywords::Yield.name() ||
id.name == keywords::Proc.name() && edition() == Edition::Edition2015 ||
id.name == keywords::Async.name() && edition() == Edition::Edition2018
}
/// Returns `true` if the token is either a special identifier or a keyword.
pub fn is_reserved_ident(id: ast::Ident) -> bool {
is_special_ident(id) || is_used_keyword(id) || is_unused_keyword(id)
}
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug)]
pub enum Token { pub enum Token {
/* Expression-operator symbols. */ /* Expression-operator symbols. */
@ -256,7 +213,7 @@ impl Token {
/// Recovers a `Token` from an `ast::Ident`. This creates a raw identifier if necessary. /// Recovers a `Token` from an `ast::Ident`. This creates a raw identifier if necessary.
pub fn from_ast_ident(ident: ast::Ident) -> Token { pub fn from_ast_ident(ident: ast::Ident) -> Token {
Ident(ident, is_raw_guess(ident)) Ident(ident, ident.is_raw_guess())
} }
/// Returns `true` if the token starts with '>'. /// Returns `true` if the token starts with '>'.
@ -436,7 +393,7 @@ impl Token {
pub fn is_path_segment_keyword(&self) -> bool { pub fn is_path_segment_keyword(&self) -> bool {
match self.ident() { match self.ident() {
Some((id, false)) => is_path_segment_keyword(id), Some((id, false)) => id.is_path_segment_keyword(),
_ => false, _ => false,
} }
} }
@ -445,7 +402,7 @@ impl Token {
// unnamed method parameters, crate root module, error recovery etc. // unnamed method parameters, crate root module, error recovery etc.
pub fn is_special_ident(&self) -> bool { pub fn is_special_ident(&self) -> bool {
match self.ident() { match self.ident() {
Some((id, false)) => is_special_ident(id), Some((id, false)) => id.is_special(),
_ => false, _ => false,
} }
} }
@ -453,7 +410,7 @@ impl Token {
/// Returns `true` if the token is a keyword used in the language. /// Returns `true` if the token is a keyword used in the language.
pub fn is_used_keyword(&self) -> bool { pub fn is_used_keyword(&self) -> bool {
match self.ident() { match self.ident() {
Some((id, false)) => is_used_keyword(id), Some((id, false)) => id.is_used_keyword(),
_ => false, _ => false,
} }
} }
@ -461,7 +418,7 @@ impl Token {
/// Returns `true` if the token is a keyword reserved for possible future use. /// Returns `true` if the token is a keyword reserved for possible future use.
pub fn is_unused_keyword(&self) -> bool { pub fn is_unused_keyword(&self) -> bool {
match self.ident() { match self.ident() {
Some((id, false)) => is_unused_keyword(id), Some((id, false)) => id.is_unused_keyword(),
_ => false, _ => false,
} }
} }
@ -469,7 +426,7 @@ impl Token {
/// Returns `true` if the token is either a special identifier or a keyword. /// Returns `true` if the token is either a special identifier or a keyword.
pub fn is_reserved_ident(&self) -> bool { pub fn is_reserved_ident(&self) -> bool {
match self.ident() { match self.ident() {
Some((id, false)) => is_reserved_ident(id), Some((id, false)) => id.is_reserved(),
_ => false, _ => false,
} }
} }

View file

@ -2374,7 +2374,7 @@ impl<'a> State<'a> {
} }
pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> { pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
if token::is_raw_guess(ident) { if ident.is_raw_guess() {
self.s.word(&format!("r#{}", ident))?; self.s.word(&format!("r#{}", ident))?;
} else { } else {
self.s.word(&ident.name.as_str())?; self.s.word(&ident.name.as_str())?;

View file

@ -300,6 +300,12 @@ impl Span {
self.ctxt().outer().expn_info().map(|i| i.call_site) self.ctxt().outer().expn_info().map(|i| i.call_site)
} }
/// Edition of the crate from which this span came.
pub fn edition(self) -> edition::Edition {
self.ctxt().outer().expn_info().map_or_else(|| hygiene::default_edition(),
|einfo| einfo.callee.edition)
}
/// Return the source callee. /// Return the source callee.
/// ///
/// Returns None if the supplied span has no expansion trace, /// Returns None if the supplied span has no expansion trace,

View file

@ -12,6 +12,7 @@
//! allows bidirectional lookup; i.e. given a value, one can easily find the //! allows bidirectional lookup; i.e. given a value, one can easily find the
//! type, and vice versa. //! type, and vice versa.
use edition::Edition;
use hygiene::SyntaxContext; use hygiene::SyntaxContext;
use {Span, DUMMY_SP, GLOBALS}; use {Span, DUMMY_SP, GLOBALS};
@ -318,7 +319,7 @@ macro_rules! declare_keywords {(
// NB: leaving holes in the ident table is bad! a different ident will get // NB: leaving holes in the ident table is bad! a different ident will get
// interned with the id from the hole, but it will be between the min and max // interned with the id from the hole, but it will be between the min and max
// of the reserved words, and thus tagged as "reserved". // of the reserved words, and thus tagged as "reserved".
// After modifying this list adjust `is_special_ident`, `is_used_keyword`/`is_unused_keyword`, // After modifying this list adjust `is_special`, `is_used_keyword`/`is_unused_keyword`,
// this should be rarely necessary though if the keywords are kept in alphabetic order. // this should be rarely necessary though if the keywords are kept in alphabetic order.
declare_keywords! { declare_keywords! {
// Special reserved identifiers used internally for elided lifetimes, // Special reserved identifiers used internally for elided lifetimes,
@ -399,6 +400,60 @@ declare_keywords! {
(63, Union, "union") (63, Union, "union")
} }
impl Symbol {
fn is_unused_keyword_2015(self) -> bool {
self == keywords::Proc.name()
}
fn is_unused_keyword_2018(self) -> bool {
self == keywords::Async.name()
}
}
impl Ident {
// Returns true for reserved identifiers used internally for elided lifetimes,
// unnamed method parameters, crate root module, error recovery etc.
pub fn is_special(self) -> bool {
self.name <= keywords::Underscore.name()
}
/// Returns `true` if the token is a keyword used in the language.
pub fn is_used_keyword(self) -> bool {
self.name >= keywords::As.name() && self.name <= keywords::While.name()
}
/// Returns `true` if the token is a keyword reserved for possible future use.
pub fn is_unused_keyword(self) -> bool {
// Note: `span.edition()` is relatively expensive, don't call it unless necessary.
self.name >= keywords::Abstract.name() && self.name <= keywords::Yield.name() ||
self.name.is_unused_keyword_2015() && self.span.edition() == Edition::Edition2015 ||
self.name.is_unused_keyword_2018() && self.span.edition() == Edition::Edition2018
}
/// Returns `true` if the token is either a special identifier or a keyword.
pub fn is_reserved(self) -> bool {
self.is_special() || self.is_used_keyword() || self.is_unused_keyword()
}
/// A keyword or reserved identifier that can be used as a path segment.
pub fn is_path_segment_keyword(self) -> bool {
self.name == keywords::Super.name() ||
self.name == keywords::SelfValue.name() ||
self.name == keywords::SelfType.name() ||
self.name == keywords::Extern.name() ||
self.name == keywords::Crate.name() ||
self.name == keywords::CrateRoot.name() ||
self.name == keywords::DollarCrate.name()
}
// We see this identifier in a normal identifier position, like variable name or a type.
// How was it written originally? Did it use the raw form? Let's try to guess.
pub fn is_raw_guess(self) -> bool {
self.name != keywords::Invalid.name() &&
self.is_reserved() && !self.is_path_segment_keyword()
}
}
// If an interner exists, return it. Otherwise, prepare a fresh one. // If an interner exists, return it. Otherwise, prepare a fresh one.
#[inline] #[inline]
fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T { fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {