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