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