mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-03 02:23:20 +00:00
syntax: dismantle ast_util.
This commit is contained in:
parent
ef4c7241f8
commit
7bebe80bc2
@ -908,14 +908,6 @@ pub fn noop_fold_item<T: Folder>(item: Item, folder: &mut T) -> Item {
|
||||
let Item { id, name, attrs, node, vis, span } = item;
|
||||
let id = folder.new_id(id);
|
||||
let node = folder.fold_item_underscore(node);
|
||||
// FIXME: we should update the impl_pretty_name, but it uses pretty printing.
|
||||
// let ident = match node {
|
||||
// // The node may have changed, recompute the "pretty" impl name.
|
||||
// ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => {
|
||||
// impl_pretty_name(maybe_trait, Some(&**ty))
|
||||
// }
|
||||
// _ => ident
|
||||
// };
|
||||
|
||||
Item {
|
||||
id: id,
|
||||
|
@ -27,11 +27,13 @@
|
||||
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute};
|
||||
use syntax::ast_util;
|
||||
use syntax::attr::ThinAttributesExt;
|
||||
use syntax::codemap::Span;
|
||||
use hir::*;
|
||||
|
||||
use std::cmp;
|
||||
use std::u32;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum FnKind<'a> {
|
||||
/// fn foo() or extern "Abi" fn foo()
|
||||
@ -837,6 +839,54 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
|
||||
walk_list!(visitor, visit_attribute, &arm.attrs);
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct IdRange {
|
||||
pub min: NodeId,
|
||||
pub max: NodeId,
|
||||
}
|
||||
|
||||
impl IdRange {
|
||||
pub fn max() -> IdRange {
|
||||
IdRange {
|
||||
min: u32::MAX,
|
||||
max: u32::MIN,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty(&self) -> bool {
|
||||
self.min >= self.max
|
||||
}
|
||||
|
||||
pub fn add(&mut self, id: NodeId) {
|
||||
self.min = cmp::min(self.min, id);
|
||||
self.max = cmp::max(self.max, id + 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IdVisitingOperation {
|
||||
fn visit_id(&mut self, node_id: NodeId);
|
||||
}
|
||||
|
||||
pub struct IdRangeComputingVisitor {
|
||||
pub result: IdRange,
|
||||
}
|
||||
|
||||
impl IdRangeComputingVisitor {
|
||||
pub fn new() -> IdRangeComputingVisitor {
|
||||
IdRangeComputingVisitor { result: IdRange::max() }
|
||||
}
|
||||
|
||||
pub fn result(&self) -> IdRange {
|
||||
self.result
|
||||
}
|
||||
}
|
||||
|
||||
impl IdVisitingOperation for IdRangeComputingVisitor {
|
||||
fn visit_id(&mut self, id: NodeId) {
|
||||
self.result.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IdVisitor<'a, O: 'a> {
|
||||
operation: &'a mut O,
|
||||
|
||||
@ -853,7 +903,7 @@ pub struct IdVisitor<'a, O: 'a> {
|
||||
skip_members: bool,
|
||||
}
|
||||
|
||||
impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> {
|
||||
impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> {
|
||||
pub fn new(operation: &'a mut O) -> IdVisitor<'a, O> {
|
||||
IdVisitor { operation: operation, skip_members: false }
|
||||
}
|
||||
@ -868,7 +918,7 @@ impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
|
||||
impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
|
||||
fn visit_mod(&mut self, module: &Mod, _: Span, node_id: NodeId) {
|
||||
self.operation.visit_id(node_id);
|
||||
walk_mod(self, module)
|
||||
@ -1012,8 +1062,8 @@ pub fn compute_id_range_for_fn_body(fk: FnKind,
|
||||
body: &Block,
|
||||
sp: Span,
|
||||
id: NodeId)
|
||||
-> ast_util::IdRange {
|
||||
let mut visitor = ast_util::IdRangeComputingVisitor { result: ast_util::IdRange::max() };
|
||||
-> IdRange {
|
||||
let mut visitor = IdRangeComputingVisitor { result: IdRange::max() };
|
||||
let mut id_visitor = IdVisitor::new(&mut visitor);
|
||||
id_visitor.visit_fn(fk, decl, body, sp, id);
|
||||
id_visitor.operation.result
|
||||
|
@ -39,7 +39,6 @@ use std::cell::RefCell;
|
||||
use std::cmp;
|
||||
use std::default::Default as StdDefault;
|
||||
use std::mem;
|
||||
use syntax::ast_util::{self, IdVisitingOperation};
|
||||
use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::errors::DiagnosticBuilder;
|
||||
@ -48,7 +47,7 @@ use syntax::ast;
|
||||
use syntax::attr::ThinAttributesExt;
|
||||
use hir;
|
||||
use hir::intravisit as hir_visit;
|
||||
use hir::intravisit::IdVisitor;
|
||||
use hir::intravisit::{IdVisitor, IdVisitingOperation};
|
||||
use syntax::visit as ast_visit;
|
||||
|
||||
/// Information about the registered lints.
|
||||
@ -654,16 +653,6 @@ impl<'a> EarlyContext<'a> {
|
||||
level_stack: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_ids<F>(&mut self, f: F)
|
||||
where F: FnOnce(&mut ast_util::IdVisitor<EarlyContext>)
|
||||
{
|
||||
let mut v = ast_util::IdVisitor {
|
||||
operation: self,
|
||||
visited_outermost: false,
|
||||
};
|
||||
f(&mut v);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LateContext<'a, 'tcx> {
|
||||
@ -928,7 +917,6 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> {
|
||||
fn visit_item(&mut self, it: &ast::Item) {
|
||||
self.with_lint_attrs(&it.attrs, |cx| {
|
||||
run_lints!(cx, check_item, early_passes, it);
|
||||
cx.visit_ids(|v| v.visit_item(it));
|
||||
ast_visit::walk_item(cx, it);
|
||||
run_lints!(cx, check_item_post, early_passes, it);
|
||||
})
|
||||
@ -1042,7 +1030,6 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> {
|
||||
fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
|
||||
self.with_lint_attrs(&trait_item.attrs, |cx| {
|
||||
run_lints!(cx, check_trait_item, early_passes, trait_item);
|
||||
cx.visit_ids(|v| v.visit_trait_item(trait_item));
|
||||
ast_visit::walk_trait_item(cx, trait_item);
|
||||
run_lints!(cx, check_trait_item_post, early_passes, trait_item);
|
||||
});
|
||||
@ -1051,7 +1038,6 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> {
|
||||
fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
|
||||
self.with_lint_attrs(&impl_item.attrs, |cx| {
|
||||
run_lints!(cx, check_impl_item, early_passes, impl_item);
|
||||
cx.visit_ids(|v| v.visit_impl_item(impl_item));
|
||||
ast_visit::walk_impl_item(cx, impl_item);
|
||||
run_lints!(cx, check_impl_item_post, early_passes, impl_item);
|
||||
});
|
||||
@ -1099,18 +1085,6 @@ impl<'a, 'tcx> IdVisitingOperation for LateContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a> IdVisitingOperation for EarlyContext<'a> {
|
||||
fn visit_id(&mut self, id: ast::NodeId) {
|
||||
match self.sess.lints.borrow_mut().remove(&id) {
|
||||
None => {}
|
||||
Some(lints) => {
|
||||
for (lint_id, span, msg) in lints {
|
||||
self.span_lint(lint_id.lint, span, &msg[..])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This lint pass is defined here because it touches parts of the `LateContext`
|
||||
// that we don't want to expose. It records the lint level at certain AST
|
||||
@ -1292,11 +1266,12 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
|
||||
|
||||
// Visit the whole crate.
|
||||
cx.with_lint_attrs(&krate.attrs, |cx| {
|
||||
cx.visit_id(ast::CRATE_NODE_ID);
|
||||
cx.visit_ids(|v| {
|
||||
v.visited_outermost = true;
|
||||
ast_visit::walk_crate(v, krate);
|
||||
});
|
||||
// Lints may be assigned to the whole crate.
|
||||
if let Some(lints) = cx.sess.lints.borrow_mut().remove(&ast::CRATE_NODE_ID) {
|
||||
for (lint_id, span, msg) in lints {
|
||||
cx.span_lint(lint_id.lint, span, &msg[..])
|
||||
}
|
||||
}
|
||||
|
||||
// since the root module isn't visited as an item (because it isn't an
|
||||
// item), warn for it here.
|
||||
|
@ -38,14 +38,13 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::path::PathBuf;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util::{IdVisitingOperation};
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ptr::P;
|
||||
use syntax::parse::token::InternedString;
|
||||
use rustc_back::target::Target;
|
||||
use hir;
|
||||
use hir::intravisit::{IdVisitor, Visitor};
|
||||
use hir::intravisit::{IdVisitor, IdVisitingOperation, Visitor};
|
||||
|
||||
pub use self::DefLike::{DlDef, DlField, DlImpl};
|
||||
pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown};
|
||||
|
@ -21,12 +21,11 @@ use std::io;
|
||||
use std::mem;
|
||||
use std::usize;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util::IdRange;
|
||||
use syntax::print::pp;
|
||||
use syntax::print::pprust::PrintState;
|
||||
use util::nodemap::NodeMap;
|
||||
use hir;
|
||||
use hir::intravisit;
|
||||
use hir::intravisit::{self, IdRange};
|
||||
use hir::print as pprust;
|
||||
|
||||
|
||||
|
@ -28,9 +28,9 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::usize;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::codemap::Span;
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::IdRange;
|
||||
|
||||
#[path="fragments.rs"]
|
||||
pub mod fragments;
|
||||
@ -602,7 +602,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
pub fn new(move_data: MoveData<'tcx>,
|
||||
tcx: &'a TyCtxt<'tcx>,
|
||||
cfg: &cfg::CFG,
|
||||
id_range: ast_util::IdRange,
|
||||
id_range: IdRange,
|
||||
decl: &hir::FnDecl,
|
||||
body: &hir::Block)
|
||||
-> FlowedMoveData<'a, 'tcx> {
|
||||
|
@ -34,11 +34,10 @@ use std::iter::{FromIterator, IntoIterator, repeat};
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::{Pat, PatKind};
|
||||
use rustc::hir::intravisit::{self, IdVisitor, Visitor, FnKind};
|
||||
use rustc::hir::intravisit::{self, IdVisitor, IdVisitingOperation, Visitor, FnKind};
|
||||
use rustc_back::slice;
|
||||
|
||||
use syntax::ast::{self, DUMMY_NODE_ID, NodeId};
|
||||
use syntax::ast_util;
|
||||
use syntax::codemap::{Span, Spanned, DUMMY_SP};
|
||||
use rustc::hir::fold::{Folder, noop_fold_pat};
|
||||
use rustc::hir::print::pat_to_string;
|
||||
@ -460,7 +459,7 @@ struct RenamingRecorder<'map> {
|
||||
renaming_map: &'map mut FnvHashMap<(NodeId, Span), NodeId>
|
||||
}
|
||||
|
||||
impl<'map> ast_util::IdVisitingOperation for RenamingRecorder<'map> {
|
||||
impl<'map> IdVisitingOperation for RenamingRecorder<'map> {
|
||||
fn visit_id(&mut self, node_id: NodeId) {
|
||||
let key = (node_id, self.origin_span);
|
||||
self.renaming_map.insert(key, self.substituted_node_id);
|
||||
|
@ -18,6 +18,7 @@ use rustc::session::Session;
|
||||
use rustc::hir;
|
||||
use rustc::hir::fold;
|
||||
use rustc::hir::fold::Folder;
|
||||
use rustc::hir::intravisit::{IdRange, IdRangeComputingVisitor, IdVisitingOperation};
|
||||
|
||||
use common as c;
|
||||
use cstore;
|
||||
@ -36,7 +37,7 @@ use middle::region;
|
||||
use rustc::ty::subst;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
|
||||
use syntax::{ast, ast_util, codemap};
|
||||
use syntax::{ast, codemap};
|
||||
use syntax::ast::NodeIdAssigner;
|
||||
use syntax::ptr::P;
|
||||
|
||||
@ -61,8 +62,8 @@ use serialize::EncoderHelpers;
|
||||
struct DecodeContext<'a, 'b, 'tcx: 'a> {
|
||||
tcx: &'a TyCtxt<'tcx>,
|
||||
cdata: &'b cstore::crate_metadata,
|
||||
from_id_range: ast_util::IdRange,
|
||||
to_id_range: ast_util::IdRange,
|
||||
from_id_range: IdRange,
|
||||
to_id_range: IdRange,
|
||||
// Cache the last used filemap for translating spans as an optimization.
|
||||
last_filemap_index: Cell<usize>,
|
||||
}
|
||||
@ -178,13 +179,13 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
|
||||
// Enumerating the IDs which appear in an AST
|
||||
|
||||
fn reserve_id_range(sess: &Session,
|
||||
from_id_range: ast_util::IdRange) -> ast_util::IdRange {
|
||||
from_id_range: IdRange) -> IdRange {
|
||||
// Handle the case of an empty range:
|
||||
if from_id_range.empty() { return from_id_range; }
|
||||
let cnt = from_id_range.max - from_id_range.min;
|
||||
let to_id_min = sess.reserve_node_ids(cnt);
|
||||
let to_id_max = to_id_min + cnt;
|
||||
ast_util::IdRange { min: to_id_min, max: to_id_max }
|
||||
IdRange { min: to_id_min, max: to_id_max }
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
|
||||
@ -705,7 +706,7 @@ struct SideTableEncodingIdVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
|
||||
rbml_w: &'a mut Encoder<'b>,
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'c, 'tcx> ast_util::IdVisitingOperation for
|
||||
impl<'a, 'b, 'c, 'tcx> IdVisitingOperation for
|
||||
SideTableEncodingIdVisitor<'a, 'b, 'c, 'tcx> {
|
||||
fn visit_id(&mut self, id: ast::NodeId) {
|
||||
encode_side_tables_for_id(self.ecx, self.rbml_w, id)
|
||||
@ -1261,8 +1262,8 @@ fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) {
|
||||
}
|
||||
}
|
||||
|
||||
fn inlined_item_id_range(v: &InlinedItem) -> ast_util::IdRange {
|
||||
let mut visitor = ast_util::IdRangeComputingVisitor::new();
|
||||
fn inlined_item_id_range(v: &InlinedItem) -> IdRange {
|
||||
let mut visitor = IdRangeComputingVisitor::new();
|
||||
v.visit_ids(&mut visitor);
|
||||
visitor.result()
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ use std::fs::{self, File};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use syntax::ast::{self, NodeId, PatKind};
|
||||
use syntax::ast_util;
|
||||
use syntax::codemap::*;
|
||||
use syntax::parse::token::{self, keywords};
|
||||
use syntax::visit::{self, Visitor};
|
||||
@ -670,7 +669,7 @@ impl<'v> Visitor<'v> for PathCollector {
|
||||
ast::BindingMode::ByValue(mt) => mt,
|
||||
};
|
||||
// collect path for either visit_local or visit_arm
|
||||
let path = ast_util::ident_to_path(path1.span, path1.node);
|
||||
let path = ast::Path::from_ident(path1.span, path1.node);
|
||||
self.collected_paths.push((p.id, path, immut, recorder::VarRef));
|
||||
}
|
||||
_ => {}
|
||||
|
@ -205,6 +205,23 @@ impl fmt::Display for Path {
|
||||
}
|
||||
}
|
||||
|
||||
impl Path {
|
||||
// convert a span and an identifier to the corresponding
|
||||
// 1-segment path
|
||||
pub fn from_ident(s: Span, identifier: Ident) -> Path {
|
||||
Path {
|
||||
span: s,
|
||||
global: false,
|
||||
segments: vec!(
|
||||
PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: PathParameters::none()
|
||||
}
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A segment of a path: an identifier, an optional lifetime, and a set of
|
||||
/// types.
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
|
@ -1,398 +0,0 @@
|
||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use ast::*;
|
||||
use ast;
|
||||
use codemap;
|
||||
use codemap::Span;
|
||||
use parse::token;
|
||||
use print::pprust;
|
||||
use ptr::P;
|
||||
use visit::{FnKind, Visitor};
|
||||
use visit;
|
||||
|
||||
use std::cmp;
|
||||
use std::u32;
|
||||
|
||||
pub fn path_name_i(idents: &[Ident]) -> String {
|
||||
// FIXME: Bad copies (#2543 -- same for everything else that says "bad")
|
||||
idents.iter().map(|i| i.to_string()).collect::<Vec<String>>().join("::")
|
||||
}
|
||||
|
||||
pub fn is_path(e: P<Expr>) -> bool {
|
||||
match e.node { ExprKind::Path(..) => true, _ => false }
|
||||
}
|
||||
|
||||
|
||||
// convert a span and an identifier to the corresponding
|
||||
// 1-segment path
|
||||
pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
|
||||
ast::Path {
|
||||
span: s,
|
||||
global: false,
|
||||
segments: vec!(
|
||||
ast::PathSegment {
|
||||
identifier: identifier,
|
||||
parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
|
||||
lifetimes: Vec::new(),
|
||||
types: P::empty(),
|
||||
bindings: P::empty(),
|
||||
})
|
||||
}
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// If path is a single segment ident path, return that ident. Otherwise, return
|
||||
// None.
|
||||
pub fn path_to_ident(path: &Path) -> Option<Ident> {
|
||||
if path.segments.len() != 1 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let segment = &path.segments[0];
|
||||
if !segment.parameters.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(segment.identifier)
|
||||
}
|
||||
|
||||
pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> P<Pat> {
|
||||
let spanned = codemap::Spanned{ span: s, node: i };
|
||||
P(Pat {
|
||||
id: id,
|
||||
node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), spanned, None),
|
||||
span: s
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate a "pretty" name for an `impl` from its type and trait.
|
||||
/// This is designed so that symbols of `impl`'d methods give some
|
||||
/// hint of where they came from, (previously they would all just be
|
||||
/// listed as `__extensions__::method_name::hash`, with no indication
|
||||
/// of the type).
|
||||
pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident {
|
||||
let mut pretty = match ty {
|
||||
Some(t) => pprust::ty_to_string(t),
|
||||
None => String::from("..")
|
||||
};
|
||||
|
||||
match *trait_ref {
|
||||
Some(ref trait_ref) => {
|
||||
pretty.push('.');
|
||||
pretty.push_str(&pprust::path_to_string(&trait_ref.path));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
token::gensym_ident(&pretty[..])
|
||||
}
|
||||
|
||||
pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
|
||||
match field.node.kind {
|
||||
ast::NamedField(_, v) | ast::UnnamedField(v) => v
|
||||
}
|
||||
}
|
||||
|
||||
// ______________________________________________________________________
|
||||
// Enumerating the IDs which appear in an AST
|
||||
|
||||
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct IdRange {
|
||||
pub min: NodeId,
|
||||
pub max: NodeId,
|
||||
}
|
||||
|
||||
impl IdRange {
|
||||
pub fn max() -> IdRange {
|
||||
IdRange {
|
||||
min: u32::MAX,
|
||||
max: u32::MIN,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty(&self) -> bool {
|
||||
self.min >= self.max
|
||||
}
|
||||
|
||||
pub fn add(&mut self, id: NodeId) {
|
||||
self.min = cmp::min(self.min, id);
|
||||
self.max = cmp::max(self.max, id + 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IdVisitingOperation {
|
||||
fn visit_id(&mut self, node_id: NodeId);
|
||||
}
|
||||
|
||||
/// A visitor that applies its operation to all of the node IDs
|
||||
/// in a visitable thing.
|
||||
|
||||
pub struct IdVisitor<'a, O:'a> {
|
||||
pub operation: &'a mut O,
|
||||
pub visited_outermost: bool,
|
||||
}
|
||||
|
||||
impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> {
|
||||
fn visit_generics_helper(&mut self, generics: &Generics) {
|
||||
for type_parameter in generics.ty_params.iter() {
|
||||
self.operation.visit_id(type_parameter.id)
|
||||
}
|
||||
for lifetime in &generics.lifetimes {
|
||||
self.operation.visit_id(lifetime.lifetime.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
|
||||
fn visit_mod(&mut self,
|
||||
module: &Mod,
|
||||
_: Span,
|
||||
node_id: NodeId) {
|
||||
self.operation.visit_id(node_id);
|
||||
visit::walk_mod(self, module)
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
|
||||
self.operation.visit_id(foreign_item.id);
|
||||
visit::walk_foreign_item(self, foreign_item)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &Item) {
|
||||
if self.visited_outermost {
|
||||
return
|
||||
} else {
|
||||
self.visited_outermost = true
|
||||
}
|
||||
|
||||
self.operation.visit_id(item.id);
|
||||
match item.node {
|
||||
ItemKind::Use(ref view_path) => {
|
||||
match view_path.node {
|
||||
ViewPathSimple(_, _) |
|
||||
ViewPathGlob(_) => {}
|
||||
ViewPathList(_, ref paths) => {
|
||||
for path in paths {
|
||||
self.operation.visit_id(path.node.id())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
visit::walk_item(self, item);
|
||||
|
||||
self.visited_outermost = false
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, local: &Local) {
|
||||
self.operation.visit_id(local.id);
|
||||
visit::walk_local(self, local)
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, block: &Block) {
|
||||
self.operation.visit_id(block.id);
|
||||
visit::walk_block(self, block)
|
||||
}
|
||||
|
||||
fn visit_stmt(&mut self, statement: &Stmt) {
|
||||
self.operation
|
||||
.visit_id(statement.node.id().expect("attempted to visit unexpanded stmt"));
|
||||
visit::walk_stmt(self, statement)
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pattern: &Pat) {
|
||||
self.operation.visit_id(pattern.id);
|
||||
visit::walk_pat(self, pattern)
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expression: &Expr) {
|
||||
self.operation.visit_id(expression.id);
|
||||
visit::walk_expr(self, expression)
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, typ: &Ty) {
|
||||
self.operation.visit_id(typ.id);
|
||||
visit::walk_ty(self, typ)
|
||||
}
|
||||
|
||||
fn visit_generics(&mut self, generics: &Generics) {
|
||||
self.visit_generics_helper(generics);
|
||||
visit::walk_generics(self, generics)
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self,
|
||||
function_kind: visit::FnKind<'v>,
|
||||
function_declaration: &'v FnDecl,
|
||||
block: &'v Block,
|
||||
span: Span,
|
||||
node_id: NodeId) {
|
||||
match function_kind {
|
||||
FnKind::Method(..) if self.visited_outermost => return,
|
||||
FnKind::Method(..) => self.visited_outermost = true,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
self.operation.visit_id(node_id);
|
||||
|
||||
match function_kind {
|
||||
FnKind::ItemFn(_, generics, _, _, _, _) => {
|
||||
self.visit_generics_helper(generics)
|
||||
}
|
||||
FnKind::Method(_, ref sig, _) => {
|
||||
self.visit_generics_helper(&sig.generics)
|
||||
}
|
||||
FnKind::Closure => {}
|
||||
}
|
||||
|
||||
for argument in &function_declaration.inputs {
|
||||
self.operation.visit_id(argument.id)
|
||||
}
|
||||
|
||||
visit::walk_fn(self,
|
||||
function_kind,
|
||||
function_declaration,
|
||||
block,
|
||||
span);
|
||||
|
||||
if let FnKind::Method(..) = function_kind {
|
||||
self.visited_outermost = false;
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_struct_field(&mut self, struct_field: &StructField) {
|
||||
self.operation.visit_id(struct_field.node.id);
|
||||
visit::walk_struct_field(self, struct_field)
|
||||
}
|
||||
|
||||
fn visit_variant_data(&mut self,
|
||||
struct_def: &VariantData,
|
||||
_: ast::Ident,
|
||||
_: &ast::Generics,
|
||||
_: NodeId,
|
||||
_: Span) {
|
||||
self.operation.visit_id(struct_def.id());
|
||||
visit::walk_struct_def(self, struct_def);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
|
||||
self.operation.visit_id(ti.id);
|
||||
visit::walk_trait_item(self, ti);
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
|
||||
self.operation.visit_id(ii.id);
|
||||
visit::walk_impl_item(self, ii);
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime: &Lifetime) {
|
||||
self.operation.visit_id(lifetime.id);
|
||||
}
|
||||
|
||||
fn visit_lifetime_def(&mut self, def: &LifetimeDef) {
|
||||
self.visit_lifetime(&def.lifetime);
|
||||
}
|
||||
|
||||
fn visit_trait_ref(&mut self, trait_ref: &TraitRef) {
|
||||
self.operation.visit_id(trait_ref.ref_id);
|
||||
visit::walk_trait_ref(self, trait_ref);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IdRangeComputingVisitor {
|
||||
pub result: IdRange,
|
||||
}
|
||||
|
||||
impl IdRangeComputingVisitor {
|
||||
pub fn new() -> IdRangeComputingVisitor {
|
||||
IdRangeComputingVisitor { result: IdRange::max() }
|
||||
}
|
||||
|
||||
pub fn result(&self) -> IdRange {
|
||||
self.result
|
||||
}
|
||||
}
|
||||
|
||||
impl IdVisitingOperation for IdRangeComputingVisitor {
|
||||
fn visit_id(&mut self, id: NodeId) {
|
||||
self.result.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the id range for a single fn body, ignoring nested items.
|
||||
pub fn compute_id_range_for_fn_body(fk: FnKind,
|
||||
decl: &FnDecl,
|
||||
body: &Block,
|
||||
sp: Span,
|
||||
id: NodeId)
|
||||
-> IdRange
|
||||
{
|
||||
let mut visitor = IdRangeComputingVisitor::new();
|
||||
let mut id_visitor = IdVisitor {
|
||||
operation: &mut visitor,
|
||||
visited_outermost: false,
|
||||
};
|
||||
id_visitor.visit_fn(fk, decl, body, sp, id);
|
||||
id_visitor.operation.result
|
||||
}
|
||||
|
||||
/// Returns true if the given pattern consists solely of an identifier
|
||||
/// and false otherwise.
|
||||
pub fn pat_is_ident(pat: P<ast::Pat>) -> bool {
|
||||
match pat.node {
|
||||
PatKind::Ident(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
// are two paths equal when compared unhygienically?
|
||||
// since I'm using this to replace ==, it seems appropriate
|
||||
// to compare the span, global, etc. fields as well.
|
||||
pub fn path_name_eq(a : &ast::Path, b : &ast::Path) -> bool {
|
||||
(a.span.source_equal(&b.span))
|
||||
&& (a.global == b.global)
|
||||
&& (segments_name_eq(&a.segments[..], &b.segments[..]))
|
||||
}
|
||||
|
||||
// are two arrays of segments equal when compared unhygienically?
|
||||
pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> bool {
|
||||
a.len() == b.len() &&
|
||||
a.iter().zip(b).all(|(s, t)| {
|
||||
s.identifier.name == t.identifier.name &&
|
||||
// FIXME #7743: ident -> name problems in lifetime comparison?
|
||||
// can types contain idents?
|
||||
s.parameters == t.parameters
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ast::*;
|
||||
use super::*;
|
||||
|
||||
fn ident_to_segment(id: Ident) -> PathSegment {
|
||||
PathSegment {identifier: id,
|
||||
parameters: PathParameters::none()}
|
||||
}
|
||||
|
||||
#[test] fn idents_name_eq_test() {
|
||||
assert!(segments_name_eq(
|
||||
&[Ident::new(Name(3),SyntaxContext(4)), Ident::new(Name(78),SyntaxContext(82))]
|
||||
.iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>(),
|
||||
&[Ident::new(Name(3),SyntaxContext(104)), Ident::new(Name(78),SyntaxContext(182))]
|
||||
.iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>()));
|
||||
assert!(!segments_name_eq(
|
||||
&[Ident::new(Name(3),SyntaxContext(4)), Ident::new(Name(78),SyntaxContext(82))]
|
||||
.iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>(),
|
||||
&[Ident::new(Name(3),SyntaxContext(104)), Ident::new(Name(77),SyntaxContext(182))]
|
||||
.iter().cloned().map(ident_to_segment).collect::<Vec<PathSegment>>()));
|
||||
}
|
||||
}
|
@ -21,7 +21,6 @@
|
||||
use ast::*;
|
||||
use ast;
|
||||
use attr::{ThinAttributes, ThinAttributesExt};
|
||||
use ast_util;
|
||||
use codemap::{respan, Span, Spanned};
|
||||
use parse::token;
|
||||
use ptr::P;
|
||||
@ -1073,13 +1072,6 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span}
|
||||
folder: &mut T) -> Item {
|
||||
let id = folder.new_id(id);
|
||||
let node = folder.fold_item_kind(node);
|
||||
let ident = match node {
|
||||
// The node may have changed, recompute the "pretty" impl name.
|
||||
ItemKind::Impl(_, _, _, ref maybe_trait, ref ty, _) => {
|
||||
ast_util::impl_pretty_name(maybe_trait, Some(&ty))
|
||||
}
|
||||
_ => ident
|
||||
};
|
||||
|
||||
Item {
|
||||
id: id,
|
||||
|
@ -91,7 +91,6 @@ pub mod syntax {
|
||||
|
||||
pub mod abi;
|
||||
pub mod ast;
|
||||
pub mod ast_util;
|
||||
pub mod attr;
|
||||
pub mod codemap;
|
||||
pub mod config;
|
||||
|
@ -44,7 +44,6 @@ use ast::{Visibility, WhereClause};
|
||||
use attr::{ThinAttributes, ThinAttributesExt, AttributesExt};
|
||||
use ast::{BinOpKind, UnOp};
|
||||
use ast;
|
||||
use ast_util::{self, ident_to_path};
|
||||
use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
|
||||
use errors::{self, DiagnosticBuilder};
|
||||
use ext::tt::macro_parser;
|
||||
@ -1577,9 +1576,14 @@ impl<'a> Parser<'a> {
|
||||
pat
|
||||
} else {
|
||||
debug!("parse_arg_general ident_to_pat");
|
||||
ast_util::ident_to_pat(ast::DUMMY_NODE_ID,
|
||||
self.last_span,
|
||||
special_idents::invalid)
|
||||
let sp = self.last_span;
|
||||
let spanned = Spanned { span: sp, node: special_idents::invalid };
|
||||
P(Pat {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable),
|
||||
spanned, None),
|
||||
span: sp
|
||||
})
|
||||
};
|
||||
|
||||
let t = self.parse_ty_sum()?;
|
||||
@ -2223,7 +2227,7 @@ impl<'a> Parser<'a> {
|
||||
ctxt: _
|
||||
}, token::Plain) => {
|
||||
self.bump();
|
||||
let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
|
||||
let path = ast::Path::from_ident(mk_sp(lo, hi), id);
|
||||
ex = ExprKind::Path(None, path);
|
||||
hi = self.last_span.hi;
|
||||
}
|
||||
@ -3679,7 +3683,7 @@ impl<'a> Parser<'a> {
|
||||
// Parse macro invocation
|
||||
let ident = self.parse_ident()?;
|
||||
let ident_span = self.last_span;
|
||||
let path = ident_to_path(ident_span, ident);
|
||||
let path = ast::Path::from_ident(ident_span, ident);
|
||||
self.bump();
|
||||
let delim = self.expect_open_delim()?;
|
||||
let tts = self.parse_seq_to_end(
|
||||
@ -5116,7 +5120,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
self.expect(&token::OpenDelim(token::Brace))?;
|
||||
self.expect(&token::CloseDelim(token::Brace))?;
|
||||
Ok((ast_util::impl_pretty_name(&opt_trait, None),
|
||||
Ok((special_idents::invalid,
|
||||
ItemKind::DefaultImpl(unsafety, opt_trait.unwrap()), None))
|
||||
} else {
|
||||
if opt_trait.is_some() {
|
||||
@ -5132,7 +5136,7 @@ impl<'a> Parser<'a> {
|
||||
impl_items.push(self.parse_impl_item()?);
|
||||
}
|
||||
|
||||
Ok((ast_util::impl_pretty_name(&opt_trait, Some(&ty)),
|
||||
Ok((special_idents::invalid,
|
||||
ItemKind::Impl(unsafety, polarity, generics, opt_trait, ty, impl_items),
|
||||
Some(attrs)))
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ use std::iter;
|
||||
use std::slice;
|
||||
use std::mem;
|
||||
use std::vec;
|
||||
use ast_util::*;
|
||||
use attr::AttrMetaMethods;
|
||||
use attr;
|
||||
use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute};
|
||||
@ -35,7 +34,7 @@ use fold;
|
||||
use parse::token::{intern, InternedString};
|
||||
use parse::{token, ParseSess};
|
||||
use print::pprust;
|
||||
use {ast, ast_util};
|
||||
use ast;
|
||||
use ptr::P;
|
||||
use util::small_vector::SmallVector;
|
||||
|
||||
@ -120,8 +119,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
||||
if ident.name != token::special_idents::invalid.name {
|
||||
self.cx.path.push(ident);
|
||||
}
|
||||
debug!("current path: {}",
|
||||
ast_util::path_name_i(&self.cx.path));
|
||||
debug!("current path: {}", path_name_i(&self.cx.path));
|
||||
|
||||
let i = if is_test_fn(&self.cx, &i) || is_bench_fn(&self.cx, &i) {
|
||||
match i.node {
|
||||
@ -349,7 +347,6 @@ enum HasTestSignature {
|
||||
NotEvenAFunction,
|
||||
}
|
||||
|
||||
|
||||
fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
|
||||
let has_test_attr = attr::contains_name(&i.attrs, "test");
|
||||
|
||||
@ -576,6 +573,11 @@ fn path_node(ids: Vec<ast::Ident> ) -> ast::Path {
|
||||
}
|
||||
}
|
||||
|
||||
fn path_name_i(idents: &[ast::Ident]) -> String {
|
||||
// FIXME: Bad copies (#2543 -- same for everything else that says "bad")
|
||||
idents.iter().map(|i| i.to_string()).collect::<Vec<String>>().join("::")
|
||||
}
|
||||
|
||||
fn mk_tests(cx: &TestCtxt) -> P<ast::Item> {
|
||||
// The vector of test_descs for this crate
|
||||
let test_descs = mk_test_descs(cx);
|
||||
@ -645,10 +647,10 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
|
||||
// creates $name: $expr
|
||||
let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr);
|
||||
|
||||
debug!("encoding {}", ast_util::path_name_i(&path[..]));
|
||||
debug!("encoding {}", path_name_i(&path[..]));
|
||||
|
||||
// path to the #[test] function: "foo::bar::baz"
|
||||
let path_string = ast_util::path_name_i(&path[..]);
|
||||
let path_string = path_name_i(&path[..]);
|
||||
let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[..]));
|
||||
|
||||
// self::test::StaticTestName($name_expr)
|
||||
|
@ -194,7 +194,6 @@ use std::vec;
|
||||
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast::{self, EnumDef, Expr, Ident, Generics, VariantData, BinOpKind, PatKind};
|
||||
use syntax::ast_util;
|
||||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::ext::base::{ExtCtxt, Annotatable};
|
||||
@ -620,7 +619,6 @@ impl<'a> TraitDef<'a> {
|
||||
// Just mark it now since we know that it'll end up used downstream
|
||||
attr::mark_used(&attr);
|
||||
let opt_trait_ref = Some(trait_ref);
|
||||
let ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&self_type));
|
||||
let unused_qual = cx.attribute(
|
||||
self.span,
|
||||
cx.meta_list(self.span,
|
||||
@ -638,7 +636,7 @@ impl<'a> TraitDef<'a> {
|
||||
|
||||
cx.item(
|
||||
self.span,
|
||||
ident,
|
||||
special_idents::invalid,
|
||||
a,
|
||||
ast::ItemKind::Impl(unsafety,
|
||||
ast::ImplPolarity::Positive,
|
||||
|
Loading…
Reference in New Issue
Block a user