| // Copyright 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 hir; |
| use hir::def_id::DefId; |
| use hir::intravisit::Visitor; |
| use ty::TyCtxt; |
| |
| use super::dep_node::DepNode; |
| |
| |
| /// Visit all the items in the krate in some order. When visiting a |
| /// particular item, first create a dep-node by calling `dep_node_fn` |
| /// and push that onto the dep-graph stack of tasks, and also create a |
| /// read edge from the corresponding AST node. This is used in |
| /// compiler passes to automatically record the item that they are |
| /// working on. |
| pub fn visit_all_items_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>, |
| mut dep_node_fn: F, |
| visitor: &mut V) |
| where F: FnMut(DefId) -> DepNode<DefId>, V: Visitor<'tcx> |
| { |
| struct TrackingVisitor<'visit, 'tcx: 'visit, F: 'visit, V: 'visit> { |
| tcx: TyCtxt<'visit, 'tcx, 'tcx>, |
| dep_node_fn: &'visit mut F, |
| visitor: &'visit mut V |
| } |
| |
| impl<'visit, 'tcx, F, V> Visitor<'tcx> for TrackingVisitor<'visit, 'tcx, F, V> |
| where F: FnMut(DefId) -> DepNode<DefId>, V: Visitor<'tcx> |
| { |
| fn visit_item(&mut self, i: &'tcx hir::Item) { |
| let item_def_id = self.tcx.map.local_def_id(i.id); |
| let task_id = (self.dep_node_fn)(item_def_id); |
| let _task = self.tcx.dep_graph.in_task(task_id.clone()); |
| debug!("Started task {:?}", task_id); |
| self.tcx.dep_graph.read(DepNode::Hir(item_def_id)); |
| self.visitor.visit_item(i); |
| debug!("Ended task {:?}", task_id); |
| } |
| } |
| |
| let krate = tcx.dep_graph.with_ignore(|| tcx.map.krate()); |
| let mut tracking_visitor = TrackingVisitor { |
| tcx: tcx, |
| dep_node_fn: &mut dep_node_fn, |
| visitor: visitor |
| }; |
| krate.visit_all_items(&mut tracking_visitor) |
| } |