rustc_passes/
debugger_visualizer.rs1use rustc_ast::{ItemKind, ast};
4use rustc_attr_parsing::AttributeParser;
5use rustc_expand::base::resolve_path;
6use rustc_hir::Attribute;
7use rustc_hir::attrs::{AttributeKind, DebugVisualizer};
8use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
9use rustc_middle::query::{LocalCrate, Providers};
10use rustc_middle::ty::TyCtxt;
11use rustc_session::Session;
12use rustc_span::sym;
13
14use crate::errors::DebugVisualizerUnreadable;
15
16impl DebuggerVisualizerCollector<'_> {
17 fn check_for_debugger_visualizer(&mut self, attrs: &[ast::Attribute]) {
18 if let Some(Attribute::Parsed(AttributeKind::DebuggerVisualizer(visualizers))) =
19 AttributeParser::parse_limited(&self.sess, attrs, &[sym::debugger_visualizer])
20 {
21 for DebugVisualizer { span, visualizer_type, path } in visualizers {
22 let file = match resolve_path(&self.sess, path.as_str(), span) {
23 Ok(file) => file,
24 Err(err) => {
25 err.emit();
26 return;
27 }
28 };
29
30 match self.sess.source_map().load_binary_file(&file) {
31 Ok((source, _)) => {
32 self.visualizers.push(DebuggerVisualizerFile::new(
33 source,
34 visualizer_type,
35 file,
36 ));
37 }
38 Err(error) => {
39 self.sess.dcx().emit_err(DebugVisualizerUnreadable {
40 span,
41 file: &file,
42 error,
43 });
44 }
45 }
46 }
47 }
48 }
49}
50
51struct DebuggerVisualizerCollector<'a> {
52 sess: &'a Session,
53 visualizers: Vec<DebuggerVisualizerFile>,
54}
55
56impl<'ast> rustc_ast::visit::Visitor<'ast> for DebuggerVisualizerCollector<'_> {
57 fn visit_item(&mut self, item: &'ast rustc_ast::Item) -> Self::Result {
58 if let ItemKind::Mod(..) = item.kind {
59 self.check_for_debugger_visualizer(&item.attrs);
60 }
61 rustc_ast::visit::walk_item(self, item);
62 }
63 fn visit_crate(&mut self, krate: &'ast ast::Crate) -> Self::Result {
64 self.check_for_debugger_visualizer(&krate.attrs);
65 rustc_ast::visit::walk_crate(self, krate);
66 }
67}
68
69fn debugger_visualizers(tcx: TyCtxt<'_>, _: LocalCrate) -> Vec<DebuggerVisualizerFile> {
71 let resolver_and_krate = tcx.resolver_for_lowering().borrow();
72 let krate = &*resolver_and_krate.1;
73
74 let mut visitor = DebuggerVisualizerCollector { sess: tcx.sess, visualizers: Vec::new() };
75 rustc_ast::visit::Visitor::visit_crate(&mut visitor, krate);
76
77 visitor.visualizers
81}
82
83pub(crate) fn provide(providers: &mut Providers) {
84 providers.debugger_visualizers = debugger_visualizers;
85}